
SQL Server难道不应该在运行时意识到永远不会满足这些条件并完全忽略它们吗?
不,绝对不是。这里有两个因素在起作用。
SQL Server不会 不 保证布尔运算符短路。有关示例,请参阅“在SQL Server上布尔运算符短路”中清楚地显示了查询优化如何颠倒布尔表达式求值的顺序。乍一看,这似乎是命令式C语言编程心态的一个错误,但对于面向声明性集的SQL世界而言,这是正确的做法。
OR是SQL SARGability的敌人。将SQL语句编译为执行计划,然后执行该计划。该计划在调用之间被重用(被缓存)。因此,SQL编译器必须生成一个适合所有单独OR情况的计划(@ AuthorType = 1 AND @ AuthorType = 2 AND @ AuthorType = 3)。从某种意义上说,当涉及到生成查询计划时,就好像@AuthorType一次具有所有值一样。结果几乎总是最糟糕的计划,因为各种OR分支相互矛盾,所以该计划无法使任何索引受益,因此最终导致扫描整个表并逐行检查行。
对于您的情况以及任何其他涉及布尔OR的情况,最好的做法是将@AuthorType移至查询之外:
IF (@AuthorType = 1) SELECt ... FROM ... WHERe ...ELSE IF (@AuthorType = 2) SELECt ... FROM ... WHERe ...ELSE ...
因为每个分支都清楚地分成了自己的语句,所以SQL可以为每种情况创建正确的访问路径。
第二个最好的方法是使用chadhoc已经建议的UNIOn ALL,并且在需要单个语句(不允许IF)的视图或其他地方使用正确的方法。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)