我看到有人交换了下面的代码:
SELECT
PK1
, PK2
, PK3
, PK4
, C
, B
, SUM(NUMERIC_1)
, SUM(NUMERIC_2)
, MAX(NUMERIC_3)
, SUM(NUMERIC_4)
FROM MATDOC_EXTRACT
WHERE A = ''
AND (
(
(
B = ''
OR B = 'K'
)
AND (
C = '01'
OR C = '02'
OR C = '07'
OR C = '08'
)
)
OR (
B = ''
AND (
C = '03'
OR C = '04'
)
)
)
GROUP BY PK1
, PK2
, PK3
, PK4
, C
, B;
对于这个
SELECT
PK1
, PK2
, PK3
, PK4
, C
, B
, SUM(NUMERIC_1)
, SUM(NUMERIC_2)
, MAX(NUMERIC_3)
, SUM(NUMERIC_4)
FROM sap.MATDOC_EXTRACT
WHERE A = N''
AND B = N''
AND C IN (N'01', N'02', N'07', N'08', N'03', N'04')
GROUP BY PK1
, PK2
, PK3
, PK4
, C
, B
UNION ALL
SELECT
PK1
, PK2
, PK3
, PK4
, C
, B
, SUM(NUMERIC_1)
, SUM(NUMERIC_2)
, MAX(NUMERIC_3)
, SUM(NUMERIC_4)
FROM sap.MATDOC_EXTRACT
WHERE A = N''
AND B = N'K'
AND C IN (N'01', N'02', N'07', N'08')
GROUP BY PK1
, PK2
, PK3
, PK4
, C
, B;
他们平等吗?
一个潜在的重要区别是,在第二种情况下,文字是
nvarchar
,而在第一种情况下,文字是varchar
。然而忽略这一方面......
是的
可以重写为
只要
predicate_a
和predicate_b
是互斥的。predicate_a
否则,与两者匹配的行将predicate_b
错误地返回两次。UNION ALL
在这种情况下,由于has的两个分支predicate_a
包含B = N''
并且predicate_b
包含B = N'K'
,则满足此条件。在您的情况下,您有 10 个不同的等式谓词
A, B, C
- 因此,如果您有一个索引,其中这些列按某种顺序排列,那么它可能可以通过十个搜索谓词来解决。当使用 编写的查询没有给出所需的索引查找或具有其他不需要的方面时,重写
OR
as有时可能是一种有用的技术。UNION ALL
OR
如果我尝试
然后执行计划看起来像
执行计划本质上将其分解为两个单独的索引查找运算符,并将
UNION ALL
它们组合在一起在两个搜索运算符之间,完整的 10 个索引搜索范围被扩展。
由于某种原因,它似乎没有看到它们不重叠,但是有一个删除重复项的步骤。
UNION ALL
在这种情况下,重写确实避免了这种情况