SQL 2000 UNION ALL 破坏查询优化

Posted

技术标签:

【中文标题】SQL 2000 UNION ALL 破坏查询优化【英文标题】:SQL 2000 UNION ALL ruins query optimization 【发布时间】:2011-05-18 22:20:40 【问题描述】:

我有一个存储过程,它需要不到一秒钟的时间才能正常运行。用户想要该查询中另一个表中的数据,因此我将该数据与 UNION ALL 和新表中缺少的一堆虚拟列合并。

它在测试中运行良好,但是当我们将它部署到 SQL 2000 服务器时,它开始出现超时。旧查询在一秒内运行,两个新查询都在一秒内运行,但是当它们使用 UNION ALL 组合时,查询超时。

以下是查询外观的大致思路。真正的查询有大约 20 个输入参数并返回大约 30 或 40 列,但这应该给出基本思路:

CREATE PROCEDURE dbo.SearchHistory
(
    @Criteria1 bigint,
    @Criteria2 int,
    @Criteria3 varchar(10)
)
AS
BEGIN
    -- Part 1
    SELECT
        A,
        NULL AS B,
        0 AS C,
        D
    FROM TableA
    WHERE @Criteria1 IS NULL
    AND @Criteria3 IS NULL
    AND (A = @Criteria2 OR @Criteria2 IS NULL)

UNION ALL

    -- Part 2
    SELECT
        A,
        NULL AS B,
        0 AS C,
        E
    FROM TableA
    WHERE @Criteria1 IS NULL
    AND @Criteria3 IS NULL
    AND (A = @Criteria2 OR @Criteria2 IS NULL)

UNION ALL

    -- Part 3
    SELECT
        A,
        B,
        C,
        D
    FROM TableB
    WHERE (F = @Criteria1 OR @Criteria1 IS NULL)
    AND (A = @Criteria2 OR @Criteria2 IS NULL)
    AND (G = @Criteria3 OR @Criteria3 IS NULL)
END

在上面的例子中,@Criteria1 不为空,所以第 1 部分和第 2 部分将返回 0 行,而第 3 部分仅返回 3 行。但是如果我注释掉第 1 部分和第 2 部分,它会立即结束;如果我把它们留在里面,我会超时。

你如何说服 SQL Server 在这种情况下不要乱搞它的执行计划?

【问题讨论】:

UNION ALL 为您提供了什么执行计划?另外,如果您只是在 3 个单独的语句中插入 @table_variable 并在最后从中选择呢? (我认为选择列表中缺少必需的逗号导致语法错误;这是实际代码吗?) 将程序更改为CREATE PROCEDURE dbo.SearchHistory WITH RECOMPILE (... 有帮助吗? 另外,尝试用谷歌搜索一个叫做“参数嗅探”的东西 - 我感觉执行计划搞砸了...... 【参考方案1】:

我认为你的问题是因为 SQL Server 的参数嗅探。

http://elegantcode.com/2008/05/17/sql-parameter-sniffing-and-what-to-do-about-it/

http://blogs.msdn.com/b/queryoptteam/archive/2006/03/31/565991.aspx

我遇到过好几次了。有几种方法可以解决它。例如。按照@Biff MaGriff 的建议使用 WITH RECOMPILE。我发现修复的最简单方法是将所有输入参数转换为本地参数,并使用本地参数。

【讨论】:

WITH RECOMPILE 使所有查询超时,而不仅仅是@Criteria1 为非NULL 的地方。我还没有开始尝试局部变量,还有太多其他的事情要做,但我仍然打算尝试一下。【参考方案2】:

没有看到执行计划就无法回答这个问题(请将它们作为图像发布,每个部分一张,联合查询一张)。一种解决方法是使用临时表,您可以在其中分别插入零件。然而,更好的解决方案是首先修复查询。

【讨论】:

以上是关于SQL 2000 UNION ALL 破坏查询优化的主要内容,如果未能解决你的问题,请参考以下文章

union all 一定比 多条SQL性能好吗?

SQL 逻辑优化 case when 转为 union all

SQL union all 排序问题

union all 效率问题

HIVE优化(四)-union all

MySQL UNION ALL 多重使用优化