0
PID UID Req Res

1   101 C   to
2   101 A   from
3   101 B   to
4   102 A   from
5   102 B   from

以下の条件を満たすテーブルからすべてのレコードを取得するクエリを書きたいと思います。

Res='to' であるすべてのレコードの UID を取得したい。これらの特定の UID について、Req='A' のレコードを取得したいと考えています。サンプルクエリを作成しましたが、それも機能しました。以下のクエリを見つけてください。

SELECT Res,
       UID,
       Req
FROM   TABLE
WHERE  Req = 'A'
       AND UID = (SELECT DISTINCT( UID )
                  FROM   TABLE
                  WHERE  Res = 'to') 

上記のクエリの問題は、SQL Server 2008 での実行中に、わずか 15 ~ 20 レコードを取得するために 1 時間以上実行されることです。これは本番テーブルであるため、レコードの総数が大きくなります。クエリが長時間実行されている理由と、最適化されたクエリを取得できるかどうかを知りたいです。

ありがとう、プラバース

4

4 に答える 4

0

JOINサブクエリの代わりに使用してみてください。

SELECT a.Res,
       a.UID,
       a.Req
  FROM TABLE a
  JOIN (SELECT UID FROM TABLE WHERE Res = 'to' GROUP BY UID) b
       ON a.UID = b.UID
 WHERE a.Req = 'A'
于 2012-07-14T09:42:01.533 に答える
0

次の方法がより効率的である可能性があることを示唆する他の投稿を見てきました。

SELECT Res, UID, Req
FROM TABLE t
WHERE  Req = 'A' and
       exists (select * from table t2 where t2.res = 'to' and t.uid = t2.uid)

論理的には同じことを行いますが、相関サブクエリはこの場合により良いクエリ プランを生成する可能性があります。

また、選択的な Req と Res が誰であるかにも依存します (関係する行が多いか、それとも少ないか)。テーブル内の多くの行が条件を満たす場合、windows 関数を使用した別の定式化があります。

于 2012-07-14T14:36:20.900 に答える
0

クエリが非常に遅い理由は、エンジンが考慮されるすべての単一行に対しておそらくそのサブクエリを実行しており、そのクエリが暗黙的に集計されている可能性があるためです (DISTINCT を使用しているため)。これは行ごとに行う作業が多く、後で結果セットに入ると、それを実現するために多くのスワッピングを行う可能性があります。

このクエリは、結合された行が同じ UID持ち、Res = 'to' を持つという条件で、テーブルをそれ自体に結合します。行は、同じ UID で Res='to' の一致する行が少なくとも 1 つあること、および Req='A' であることの 2 つの要因に基づいてフィルタリングされます。

これは非常に高速なソリューションです。その理由は次のとおりです。クエリ エンジンは、結果セットからできるだけ早く行を削除するように最適化されています。行 PID=1、3、&5 の場合、Req != 'A' であるため、エンジンはすぐにそれらを考慮から除外します (結合も実行しません)。行 PID=2 の場合、結合は行 1 に一致し、通常は結合 3 に進むことさえありません (DISTINCT キーワードを介して (および結合からの列が選択されていないという事実を認識しているため)、 join は結果セットを変更しません)。また、PID=4 の場合、どれにも一致しません。

SELECT DISTINCT main_row.Res,
       main_row.UID,
       main_row.Req
FROM   TABLE AS main_row
JOIN   TABLE AS res_join 
       ON main_row.UID = res_join.UID 
       AND res_join.Res = 'to'
WHERE  main_row.Req = 'A'
于 2012-07-14T15:16:40.930 に答える
0

問題の原因は DISTINCT の使用にある可能性があるため、調査する価値があります。明らかに、それらは元のフォームに非常に近いです。

SELECT Res, UID, Req FROM TABLE
WHERE  Req = 'A'
    AND UID = (SELECT t2.UID FROM TABLE as t2 WHERE Res = 'to' GROUP BY t2.UID)

SELECT Res, UID, Req FROM TABLE
WHERE  Req = 'A'
    AND UID = (SELECT MIN(t2.UID) FROM TABLE as t2 WHERE Res = 'to') 
于 2012-07-14T15:45:53.097 に答える