简体   繁体   English

如果第一组内连接为空,则性能差异

[英]Performance difference if first set of inner join is empty

I have to use 5 tables of my database to obtain data and I wrote a SQL query like this:我必须使用我的数据库的 5 个表来获取数据,我写了一个这样的 SQL 查询:

SELECT *
FROM A 
INNER JOIN B ON A.id_b = B.id_b
INNER JOIN C ON B.id_c = C.id_c
INNER JOIN D ON D.id_d = C.id_d
INNER JOIN E ON E.id_e = D.id_e
WHERE A.column1 = somevalue

The columns I select doesn't matter for my explanation, but I require some columns of all tables to do the operation.我选择的列对我的解释无关紧要,但我需要所有表的一些列来执行操作。

I'd like to know: If set A is empty according to the WHERE clause requirements, will it progress on the successive inner joins?我想知道:如果根据 WHERE 子句的要求,集合 A 为空,它会在连续的内连接上取得进展吗?

Yes and no and maybe.是和否,也许。 In all likelihood, the optimizer is going to choose an execution plan that starts with A , because you have filtering conditions in the WHERE clause.优化器很可能会选择以A开头的执行计划,因为您在WHERE子句中有过滤条件。

Then, the subsequent JOIN s are going to be really fast, because the SQL engine doesn't have to do much work to JOIN an empty set to anything else.接着,随后的JOIN s的将是非常快的,因为SQL引擎没有做太多的工作JOIN一个空集,其他任何东西。

That said, there is no guarantee the the optimizer will start with the first table.也就是说,不能保证优化器将从第一个表开始。 So, this is really a happenstance, but a reasonable expectation given your filtering conditions.因此,这确实是偶然事件,但鉴于您的过滤条件,这是一个合理的期望。 Also, the subsequent JOIN s will be in the execution plan, but they will be fast, because each one will have one set that is empty.此外,后续的JOIN将在执行计划中,但它们会很快,因为每个都有一组是空的。

You can try the following methods to optimize your query performance, however the actual result depends on many factors, and you have to test them to see whether they really work for your scenario or not, or which one works best:您可以尝试以下方法来优化您的查询性能,但实际结果取决于许多因素,您必须对其进行测试以查看它们是否真的适用于您的场景,或者哪种方法最有效:

  • Use stored procedure and parametrized somevalue instead of raw query;使用存储过程和参数化somevalue代替原始查询;
  • Make sure there is an index on A.column1 and rebuild it regularly (clustered index is better if possible)确保 A.column1 上有索引并定期重建(如果可能,聚集索引更好)
  • Use "with (Forceseek)" on table a;在表 a 上使用“with (Forceseek)”; (assuming that the index on column1 is already created) (假设已经创建了 column1 上的索引)
  • Use "OPTION (FAST 1)";使用“选项(快速 1)”;
  • Store the result of table A to a temporary table first, then use the temporary table for the following script.先把A表的结果存到一个临时表中,然后在下面的脚本中使用这个临时表。 (This method should be the most effective one in most cases and table A is guaranteed to be executed first.) (这个方法在大多数情况下应该是最有效的,并且保证首先执行表A。)

Scripts will be like this:脚本将是这样的:

SELECT * 
INTO #A 
FROM A
WHERE A.column1 = somevalue

SELECT * 
FROM #A 
INNER JOIN B ON A.id_b = B.id_b
INNER JOIN C ON B.id_c = C.id_c
INNER JOIN D ON D.id_d = C.id_d
INNER JOIN E ON E.id_e = D.id_e

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM