0
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') 

嗨,我有这个查询,我正在尝试优化。我试图将其转换为删除联合和 In 以更具可读性但失败了。我正在努力提高效率,可能只使用 EXISTS 和 NOT EXISTS。

4

5 回答 5

2

我认为你可以用这种方式重写你的嵌套/存在:

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'
)
于 2013-01-25T18:18:44.397 回答
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'
)
于 2013-01-25T18:15:39.260 回答
1

只需将您的 UNION 子句更改为 UNION ALL。仅此一项就应该对一些人有所帮助。

为了能够在不让我们盲目猜测的情况下为您提供更多帮助,您必须向我们提供表、键和索引定义以及查询计划。

于 2013-01-25T18:18:25.200 回答
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')

请参阅我对死锁和 with (nolock) 的评论。
我不考虑使用(nolock)kludge并经常使用它。
如果您看到很多死锁,那么您需要查看它。

索引 cu、ic 和 ptype。
然后测试不同版本的查询,看看执行计划。
这是查询优化器可能遇到问题的查询类型。
查询优化器基于统计数据,甚至可以更改执行计划。
您可能需要包含连接的表提示。

于 2013-01-25T18:12:50.593 回答
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

于 2013-01-25T18:14:09.887 回答