WHERE子句中的评估顺序和查询真的很慢

时间:2012-01-27 16:14:17

标签: sql tsql database-design

SELECT ... WHERE expr1 and expr2 or expr3 or expr4

此查询在>中执行3分钟。

SELECT ... WHERE expr1 and (expr2 or expr3 or expr4)

这会立即终止。

我原本期望不同的结果,而不是性能。任何人都可以解释原因吗?

背景:选择左外连接 7表,但它们不是很大(< 10k记录最大的一个)。 Here is the query,但我强烈建议它是难以理解的,因为它是由遗留系统上的一个非常古老的工具生成的,整个项目很难处理。我只对上面描述的问题感兴趣

2 个答案:

答案 0 :(得分:2)

第二个版本要求expr1对所有记录都为真。如果expr1仅依赖于单个表,那么DBMS可以"push" the predicate "down"并在执行连接之前进行过滤。 (即使它依赖于多个表,它至少可以在某些连接之前被推下。)这可能会使许多更少的记录被检查,并且更好使用指数。

答案 1 :(得分:2)

OR比较需要很长时间,因为您需要检查每个记录的每种可能性。

OR括在括号中将它们视为一组并允许短路评估。

您的第一个查询评估为:

WHERE (Expr1 --required
AND   Expr2) --required
OR    Expr3 --but you can skip those to find this
OR    Expr4 --or this

检查所有3个条件需要更多时间。

您的第二个评估Expr1,然后可以快速检查子集中的三个条件。我猜测其中一个是索引的,可以非常有效地检查,这减少了检查其他人所需的结果集。