我在 Where 子句中有一个包含三个内部连接语句的查询。执行查询大约需要 2 分钟。如果我只是更改两个内部连接的顺序,性能下降到 40 秒。
除了改变内部连接的顺序之外什么都不做怎么会对查询性能产生如此巨大的影响呢?我原以为优化器会解决所有这些问题。
我在 Where 子句中有一个包含三个内部连接语句的查询。执行查询大约需要 2 分钟。如果我只是更改两个内部连接的顺序,性能下降到 40 秒。
除了改变内部连接的顺序之外什么都不做怎么会对查询性能产生如此巨大的影响呢?我原以为优化器会解决所有这些问题。
SQL 是声明性的,即 JOIN 顺序无关紧要。
然而,它可以在实践中,比如说,如果它是一个复杂的查询,当优化器没有探索所有选项时(理论上可能需要几个月)。
另一种选择是,如果您重新排序并得到不同的结果,这是一个非常不同的查询,但这通常与 OUTER JOIN 一起使用。
它也可能是指定 ON 子句的方式 如果您重新排序 FROM 子句,它必须更改。除非您使用的是旧的(和糟糕的)JOIN-in-the-WHERE-clause。
最后,如果您担心,您可以使用括号来更改评估顺序以明确您的意图,例如,首先过滤大表以生成派生表。
Because by changing the order of the joins, SQL Server is coming up with a different execution plan for your query (chances are it's changing the way it's filtering the tables based on your joins).
In this case, I'm guessing you have several large tables...one of which performs the majority of the filtering.
In one query, your joins are joining several of the large tables together and then filtering the records at the end.
In the other, you are filtering the first table down to a much smaller sub-set of the data...and then joining the rest of the tables in. Since that initial table got filtered before joining the other large recordsets, performance is much better.
You could always verify but running the query with the 'Show query plan' option enabled and see what the query plan is for the two different join orders.
I would have thought it was smart enough to do that as well, but clearly it's still performing the joins in the order you explicitly list them... As to why that affects the performance, if the first join produces an intermediate result set of only 100 records in one ordering scheme, then the second join will be from that 100-record set to the third table. If putting the other join first produces a first intermediate result set of one million records, then the second join will be from a one million row result set to the third table...