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

こんにちは私は私が最適化しようとしているこのクエリを持っています。ユニオンとインをより読みやすいものに変換するために変換しようとしましたが、失敗しました。おそらくEXISTSのみを使用し、EXISTSは使用しないことで、より効率的にしようとしています。

4

5 に答える 5

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 に答える
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'
)
于 2013-01-25T18:18:44.397 に答える
1

UNION句をUNIONALLに変更するだけです。それだけでいくつかの助けになるはずです。

私たちが盲目的に推測することなくそれ以上のことを支援できるようにするには、テーブル、キー、インデックスの定義、およびクエリプランを提供する必要があります。

于 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

ユニオン交差は、クエリオプティマイザがどれだけ賢かったかによって、より速くなる可能性があります

(   
    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'

オプティマイザーがこれらの第2レベルの結合で愚かになるのを見たことがあります。

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)クラッジを考慮せず、それを頻繁に使用します。
多くのデッドロックが発生している場合は、それを確認する必要があります。

インデックス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 に答える