Sql WHERE子句中的优化似乎不适用于UNION
我尝试了以下格式的SQL脚本。(有多个连接可以生成set1、set2和set3,但为了简单起见,删除了它们) 当Sql WHERE子句中的优化似乎不适用于UNION,sql,sql-server,sql-server-2014,Sql,Sql Server,Sql Server 2014,我尝试了以下格式的SQL脚本。(有多个连接可以生成set1、set2和set3,但为了简单起见,删除了它们) 当@include=0时,最后一个联合将被忽略。这也是我在查找有条件地执行UNION时看到的情况 但我不是这样;即使当@include=0时,查询也需要很长时间才能执行。如果我注释掉最后一部分,查询将执行得更快 SELECT * FROM ( SELECT * FROM Set1 WHERE someConditions UNION SELECT * FR
@include=0
时,最后一个联合
将被忽略。这也是我在查找有条件地执行UNION
时看到的情况
但我不是这样;即使当@include=0
时,查询也需要很长时间才能执行。如果我注释掉最后一部分,查询将执行得更快
SELECT * FROM (
SELECT * FROM Set1
WHERE someConditions
UNION
SELECT * FROM Set2
WHERE someConditions
--UNION
--SELECT * FROM Set3
--WHERE @include = 1 AND otherConditions..
) as t
ORDER BY ...
为什么编译器无法获取此信息?有没有办法在这种情况下优化查询?对我来说,选项(重新编译)在类似的测试设置中运行得很好-在没有提示的情况下重用糟糕的计划(假设以前使用@include=1运行),但在使用重新编译时创建一个新的、更好的计划
如果这对您不起作用,您可以尝试使用If将其拆分为两个不同的语句,例如:
BEGIN
IF @include = 1
BEGIN
SELECT * FROM Set1
WHERE someConditions
UNION
SELECT * FROM Set2
WHERE someConditions
UNION
SELECT * FROM Set3
WHERE otherConditions..
END
ELSE
BEGIN
SELECT * FROM Set1
WHERE someConditions
UNION
SELECT * FROM Set2
WHERE someConditions
END
END
可以尝试使用?或使用动态SQL创建一个只包含所需部分的查询。另外,您真的需要
UNION
,还是UNION-ALL
仍能产生正确的结果UNION
是一种成本更高的运算符,只有在您真正需要时才应使用。这只是一种预感,但您能否尝试将所有出现的“UNION”替换为“UNION all”,然后将外部的“select”转换为“select distinct”。查询引擎可能更倾向于以这种方式分别处理这三个查询组件。选项(重新编译)
和UNION ALL
对我没有影响。可能不得不使用动态SQL作为最后手段。@eshirvana No;在末尾为整个查询添加。我们不能为内部查询添加重新编译,对吗?它导致语法错误。出于某种原因,重新编译对我没有帮助。但我喜欢这种拆分的想法,尽管这可能对维护没有好处。
BEGIN
IF @include = 1
BEGIN
SELECT * FROM Set1
WHERE someConditions
UNION
SELECT * FROM Set2
WHERE someConditions
UNION
SELECT * FROM Set3
WHERE otherConditions..
END
ELSE
BEGIN
SELECT * FROM Set1
WHERE someConditions
UNION
SELECT * FROM Set2
WHERE someConditions
END
END