SELECT *
FROM sec
WHERE sec.cu IN (SELECT s.cu
FROM sec s WITH (nolock)
WHERE EXISTS (SELECT *
FROM hact h WITH ( nolock),
JOIN dport p WITH ( nolock) ON h.ic = p.ic
WHERE s.cu = h.cu )
UNION
SELECT s.cu
FROM sec s WITH (nolock)
WHERE EXISTS(SELECT *
FROM schanges c WITH ( nolock)
WHERE s.cu = c.cu)
UNION
SELECT s.cu
FROM sec s WITH (nolock)
WHERE s.cu IN (SELECT DISTINCT cu
FROM suk WITH (nolock)))
AND EXISTS (SELECT *
FROM hact h WITH (nolock)
JOIN port p WITH (nolock)
ON h.ic = p.ic
WHERE sec.cu = h.cu
AND p.ptype = 'X')
嗨,我有这个问题,我正在尝试优化。我试图将其转换为删除联合和转换为更可读但失败。我试图提高效率,可能只使用EXISTS而不是EXISTS。
答案 0 :(得分:2)
这是一个应该在功能上等同的简化版本:
SELECT s.*
FROM sec s WITH (nolock)
WHERE (
EXISTS (
SELECT *
FROM hact h WITH ( nolock)
JOIN dport p WITH ( nolock)
ON h.ic = p.ic
WHERE s.cu = h.cu
) OR EXISTS (
SELECT *
FROM schanges c WITH ( nolock)
WHERE s.cu = c.cu
) OR EXISTS (
SELECT *
FROM suk WITH (nolock)
WHERE s.cu = suk.cu
)
) AND EXISTS (
SELECT *
FROM hact h WITH (nolock)
JOIN port p WITH (nolock)
ON h.ic = p.ic
WHERE
s.cu = h.cu
AND p.ptype = 'X'
)
答案 1 :(得分:2)
我认为你可以用这种方式重写你的嵌套in / exists:
SELECT *
FROM sec
WHERE sec.cu IN (
SELECT s.cu
FROM sec s
INNER JOIN hact h ON s.cu = h.cu,
INNER JOIN dport p ON h.ic = p.ic
UNION ALL
SELECT s.cu
FROM sec s
INNER JOIN schanges c ON s.cu = c.cu)
UNION ALL
SELECT s.cu
FROM sec s
INNER JOIN suk k ON k.cu = s.cu
INNER JOIN hact h ON s.cu = h.cu
INNER JOIN port p ON h.ic = p.ic AND p.ptype = 'X'
)
甚至完全从子查询中删除sec
表:
SELECT *
FROM sec
WHERE sec.cu IN (
SELECT h.cu
FROM hact h
INNER JOIN dport p ON h.ic = p.ic
UNION ALL
SELECT cu
FROM schanges
UNION ALL
SELECT k.cu
FROM suk k
INNER JOIN hact h ON s.cu = h.cu
INNER JOIN port p ON h.ic = p.ic AND p.ptype = 'X'
)
答案 2 :(得分:1)
只需将您的UNION子句更改为UNION ALL即可。仅此一点应该有所帮助。
为了能够在没有我们盲目猜测的情况下为您提供帮助,您将不得不向我们提供表格,密钥和索引定义以及查询计划。
答案 3 :(得分:0)
未经测试,但我认为您可以使用连接
来执行此操作select distinct s.*
from sec s with (nolock)
join hatch h1 with (nolock)
on h1.cu = s.cu
join port p1 WITH (nolock)
ON h1.ic = p1.ic
AND p1.ptype = 'X'
left join hact h2 WITH ( nolock)
on h2.cu = s.cu
join port p2 WITH (nolock)
ON h2.ic = p2.ic
left join schanges c WITH ( nolock)
on s.cu = c.cu
left join suc WITH ( nolock)
on s.cu = suc.cu
where h2.cu is not null
or c.cu is not null
or suc.cu is not null
union intersect可能会更快 取决于查询优化器的智能程度
(
select s.*
from sec s with (nolock)
join hact h2 WITH (nolock)
on h2.cu = s.cu
join port p2 WITH (nolock)
ON h2.ic = p2.ic
union
select s.*
from sec s with (nolock)
join schanges c WITH ( nolock)
on s.cu = c.cu
union
select s.*
from sec s with (nolock)
left join suc WITH ( nolock)
on s.cu = suc.cu
)
intersect
select s.*
from sec s with (nolock)
join hatch h1 with (nolock)
on h1.cu = s.cu
join port p1 WITH (nolock)
ON h1.ic = p1.ic
AND p1.ptype = 'X'
我已经看到优化器在这些二级连接上变得愚蠢 如果是这样,试试
select s.*
from sec s with (nolock)
join hact h1 WITH (nolock)
on h1.cu = s.cu
where h1.ic in (select ic from where ptype = 'X')
请参阅我对死锁的评论和(nolock)
我不考虑(nolock)一个kludge并使用它很多。
如果你看到很多死锁,那么你需要看一下。
索引cu,ic和ptype。
然后测试不同版本的查询并查看执行计划
这是查询优化器可能遇到问题的查询类型
查询优化器基于统计信息,甚至可以更改执行计划
您可能需要包含联接的表提示。
答案 4 :(得分:0)
我在想:(未经测试,希望保持功能等同性)
SELECT DISTINCT s.*
FROM sec s
JOIN hact h WITH (nolock)
ON s.cu = h.cu
LEFT JOIN dport p WITH (nolock)
ON h.ic = p.ic
LEFT JOIN schanges c WITH (nolock)
ON s.cu = c.cu
LEFT JOIN suk WITH (nolock)
ON suk.cu = s.cu
JOIN port p2 WITH (nolock)
ON h.ic = p2.ic
WHERE p2.ptype = 'X' AND
(p.ic IS NOT NULL OR c.cu IS NOT NULL OR suk.cu IS NOT NULL)
修改:添加了DISTINCT