SQL Server查询表值参数的短路EXISTS语句

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL Server查询表值参数的短路EXISTS语句相关的知识,希望对你有一定的参考价值。

我使用存储过程:

在我的WHERE子句中,我使用短路(OR)来加速执行,因为查询优化器知道我的大多数输入默认为Null。这使我的查询变得灵活和快速。

我已将表值参数添加到WHERE子句中。报告的执行时间从150毫秒增加到450毫秒,读数从70,000增加到200,000。

...
WHERE
    --Integer value parameters
    AND ((@hID is Null) OR (h.ID = @hID))
    AND ((@dID is Null) OR (d.ID = @dID))
    AND ((@mID is NULL) OR (m.ID = @mID))
    --New table value parameter 
    --Execute, Processing time and read's increased. 
    --No additional JOIN added.
    AND (NOT EXISTS (SELECT Null FROM @rIDs) OR r.ID IN (SELECT r FROM @rIDs))

如何将NOT EXISTS短路或加速此查询?我已经尝试添加BIT值并在执行查询之前检查行是否在表值参数中。我找到的唯一方法是有两个查询并执行另一个查询。如果我必须修改一大堆查询或将多个表值参数添加到混合中,那就太好了。

提前致谢。

编辑:

表值参数的比较:

    AND (NOT EXISTS (SELECT Null FROM @rIDs) OR r.ID IN (SELECT r FROM @rIDs))

和整数参数:

    AND ((@rID) OR (r.ID = @rID))

在使用TVP编译0行和Integer参数null后显示类似的执行速度。我认为查询优化器在正确的庄园中是短路的,而我以前的比较是不正确的。执行计划将上述成本分为55%和45%,这是可以接受的。虽然TVP中有更多行时分割不会改变,但生成报告的时间会增加,因为必须从磁盘读取更多页面。有趣。

答案
if exists (select * from @rIDs)
    begin
    .... -- query with TVP
    end
else
    begin
    .... -- query without TVP
    end

这允许为每个查询单独执行计划。

另一答案

看起来你正在使用表变量。如果您使用临时表并将用于标准的列编入索引(在示例中为r),则将避免进行表扫描。然而,这使它成为一个多步骤的过程,但它们的回报可能是巨大的。

更具体地说,您可以将示例的最后一行更改为AND EXISTS(SELECT r FROM @rIDs WHERE r = r.ID AND NOT r IS NULL)

如果你可以发布执行计划,我可以给你一个更好的答案。单击显示估计执行计划,右键单击执行计划,然后选择将执行计划保存为...

另一答案

您可以尝试在要查询的桌子(左侧)和TVP之间进行LEFT JOIN。

以上是关于SQL Server查询表值参数的短路EXISTS语句的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server-聚焦LEFT JOIN...IS NULL AND NOT EXISTS性能分析(十七)

测试那些事儿—SQL server exists子查询

EXISTS 子句的 SQL Server 查询提示

sql语句原则

SQL Server 查询性能问题:需要替换 NOT EXISTS

SQL Server - Exists 的替代方案(子查询太多)