我必须根据表上的不存在条件选择一些行.如果我使用如下所示的union,它将在不到1秒的时间内执行.
SELECT 1 FROM dummyTable
WHERE NOT EXISTS
(
SELECT 1 FROM TABLE t
WHERE Data1 = t.Col1 AND Data2=t.Col2
UNION ALL
SELECT 1 FROM TABLE t
WHERE Data1 = t.Col2 AND Data2=t.Col1
)
Run Code Online (Sandbox Code Playgroud)
但是如果我使用OR条件,则SQL服务器正在执行一个表惰性池时需要将近一分钟.有人可以解释一下吗?
SELECT 1 FROM dummyTable
WHERE NOT EXISTS
(
SELECT 1 FROM TABLE t
WHERE ( (Data1 = t.Col1 AND Data2=t.Col2) OR (Data1 = t.Col2 AND Data2=t.Col1))
)
Run Code Online (Sandbox Code Playgroud)
问题在于您使用 OR 指定了两个适用于查询中不同表的条件。因此,非聚集索引查找必须返回大表中的大部分或全部行,因为 OR 逻辑意味着它们也可能与第二个表中的条件子句匹配。
查看上面所有三个示例中的 SQL 执行计划,并注意从大表中非聚集索引查找出来的行数。最终结果可能只返回表中 800,000 行中的 1,000 行或更少,但 OR 子句意味着该表的内容必须与第二个表中的条件交叉引用,因为 OR 意味着最终结果可能需要它们查询输出。
根据您的执行计划,索引查找可能会提取大表中的所有 800,000 行,因为它们也可能与第二个表中的 OR 子句的条件匹配。UNION ALL 是针对一个表的两个单独的查询,因此索引查找只需输出可能与该查询的条件匹配的较小结果集。
我希望这是有道理的。我在重构运行缓慢的 SQL 语句时遇到过同样的情况。
干杯,
安德烈·拉涅利
查询计划还受到表中行数的影响。表中有多少行t
?
您还可以尝试:
SELECT 1 FROM dummyTable
WHERE NOT EXISTS
(
SELECT 1 FROM TABLE t
WHERE Data1 = t.Col1 AND Data2=t.Col2
)
AND NOT EXISTS
(
SELECT 1 FROM TABLE t
WHERE Data1 = t.Col2 AND Data2=t.Col1
)
Run Code Online (Sandbox Code Playgroud)
或(针对 SQL-Server 进行更正)将使用索引:
WITH tt AS <---- a temp table with 2 rows
( SELECT Data1 AS Col1, Data2 AS Col2
UNION
SELECT Data2 AS Col1, Data1 AS Col2
)
SELECT 1 FROM dummyTable
WHERE NOT EXISTS
(
SELECT 1
FROM TABLE t
JOIN tt
ON tt.Col1 = t.Col1 AND tt.Col2=t.Col2
)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
15743 次 |
最近记录: |