SQL Server 查询表值参数的短路 EXISTS 语句
Posted
技术标签:
【中文标题】SQL Server 查询表值参数的短路 EXISTS 语句【英文标题】:Short Circuit EXISTS statment in SQL Server query for Table Valued Parameters 【发布时间】:2013-01-09 14:56:48 【问题描述】:我使用存储过程:
在我的 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))
我怎样才能短路不存在或加快这个查询?在执行查询之前,我尝试添加一个 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 中有更多行时拆分不会改变,但生成报告的时间会增加,因为必须从磁盘读取更多页面。很有趣。
【问题讨论】:
你试过option ( recompile )
在不缓存执行计划的情况下检查性能吗?
我尝试了 OPTION (RECOMPILE),查询时间增加了两倍。谢谢
【参考方案1】:
if exists (select * from @rIDs)
begin
.... -- query with TVP
end
else
begin
.... -- query without TVP
end
这允许为每个查询单独执行计划。
【讨论】:
我在我的问题中提到了这种方法,但我有大量的变量和查询需要考虑。如果找不到适合我的查询的解决方案,我可能不得不使用这种方法。 你可以试试option (recompile)
,它会强制每次查询执行都进行编译。然后将使用实际行数估计查询计划。考虑到您问题中的运行时间,这当然可以得到回报,因为典型的重新编译只需 20 毫秒。
感谢 Andomar,感谢对 option(recompile) 选项的解释【参考方案2】:
看起来您正在使用表变量。如果您使用临时表并索引您用于条件的列(在您的示例中为 r),您将避免表扫描。然而,这使它成为一个多步骤的过程,但它们的回报可能是巨大的。
为了更具体地解决您的问题,您可以将示例的最后一行更改为 AND 存在(从@rIDs 中选择 r,其中 r = r.ID 而不是 r 为 NULL)
如果您可以发布执行计划,我可以给您一个更好的答案。点击Display Estimated Execution Plan,右击执行计划,选择Save Execution Plan As...
【讨论】:
我会说the payoff *can* be huge
而不是一揽子声明暗示这是应该始终这样做的方式。您发布的语法也不正确:AND EXISTS r.ID IN ...
?
嗨,约翰,我可以在表中添加一个索引,我的问题是如果 TVP 有零行,那么我希望索引扫描是无关紧要的。我也尝试了 EXISTS r.ID IN 但它抱怨语法,这是 2012 年的功能吗?
对你和亚伦都很抱歉。我在上面编辑了我的答案。我的复制粘贴出错了。您有机会查看执行计划吗?【参考方案3】:
您可以尝试在要查询的表(左侧)和 TVP 之间进行 LEFT JOIN。
【讨论】:
以上是关于SQL Server 查询表值参数的短路 EXISTS 语句的主要内容,如果未能解决你的问题,请参考以下文章
如果不需要,SQL Server 是不是足够聪明,不会执行昂贵的查询? (短路)