我遇到了一个有趣的问题(至少对我来说很有趣)。下面是我的查询的大体概念。假设@AuthorType是存储过程的输入,并且在我放置注释的每个位置都有各种特定的条件。
SELECT *
FROM TBooks
WHERE
(--...SOME CONDITIONS)
OR
(@AuthorType = 1 AND --...DIFFERENT CONDITIONS)
OR
(@AuthorType = 2 AND --...STILL MORE CONDITIONS)我感兴趣的是,如果我在@AuthorType = 0的情况下执行这个SP,它的运行速度会比删除最后两组条件(为@AuthorType的特殊值添加条件的那两组)要慢。
SQL Server不应该在运行时意识到这些条件永远不会得到满足并完全忽略它们吗?我遇到的差异并不小;它大约使查询的长度增加了一倍(1-2秒到3-5秒)。
我是否期望SQL Server对此进行过多优化?对于特殊情况,我真的需要有3个单独的SP吗?
发布于 2009-11-11 01:27:23
难道SQL Server不应该在运行时意识到这些条件永远不会得到满足并完全忽略它们吗?
不,绝对不是。这里有两个因素在起作用。
在您的情况下,以及任何其他涉及布尔OR的情况下,最好的做法是将@AuthorType移出查询:
IF (@AuthorType = 1)
SELECT ... FROM ... WHERE ...
ELSE IF (@AuthorType = 2)
SELECT ... FROM ... WHERE ...
ELSE ...因为每个分支都清楚地划分到各自的语句中,所以SQL可以为每个单独的情况创建适当的访问路径。
下一个最好的方法是使用UNION ALL,这是chadhoc已经建议的方式,并且是视图或其他需要单个语句的地方的正确方法(允许使用no IF )。
发布于 2009-11-11 00:54:50
这是由于优化器很难处理"OR“类型的逻辑以及issues对parameter sniffing所做的事情。尝试将上面的查询更改为UNION方法,如文章here中所述。也就是说,你最终会得到多个联合在一起的语句,只有一个@AuthorType =x和,允许优化器排除AND逻辑与给定的@AuthorType不匹配的部分,并依次查找适当的索引...看起来像这样:
SELECT *
FROM TBooks
WHERE
(--...SOME CONDITIONS)
AND @AuthorType = 1 AND --...DIFFERENT CONDITIONS)
union all
SELECT *
FROM TBooks
WHERE
(--...SOME CONDITIONS)
AND @AuthorType = 2 AND --...DIFFERENT CONDITIONS)
union all
...https://stackoverflow.com/questions/1709348
复制相似问题