2

我使用存储过程:

在我的 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 参数为空进行编译后显示出相似的执行速度。我假设查询优化器在正确的庄园中短路,而我之前的比较是不正确的。执行计划将上述成本分为 55% 和 45%,这是可以接受的。尽管 TVP 中有更多行时拆分不会改变,但生成报告的时间会增加,因为必须从磁盘读取更多页面。有趣的。

4

3 回答 3

0

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

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

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

于 2013-01-09T15:10:13.790 回答
0
if exists (select * from @rIDs)
    begin
    .... -- query with TVP
    end
else
    begin
    .... -- query without TVP
    end

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

于 2013-01-09T15:02:14.927 回答
0

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

于 2019-04-10T11:58:51.637 回答