3

クエリでこの奇妙なパフォーマンスの問題が発生し、なぜこれが発生するのかを理解しようとしています。これは、クエリの簡略化された例です。

SELECT DISTINCT table1.status AS Status
FROM table1
INNER JOIN (
        SELECT DataID, MAX(VersionNum) as mVersion 
        FROM table1
        GROUP BY DataID 
    ) AS b 
    ON table1.DataID = b.DataID 
    AND table1.VersionNum = b.mVersion
INNER JOIN table2
    ON table1.table2ID = table2.ID
WHERE table2.field = @parameter

表1は、同じDataIDを持つ行で構成されており、それぞれにバージョン番号があります。その行のセットから最大の番号を選択する必要があります。

表1には、table2との結合に使用できる特定のIDが含まれています。table2から制約を追加し、パラメーターが実際にtable2に存在する場合、クエリの完了には1分以上かかり、10行が返されます。

table1に制約を追加すると、パフォーマンスの問題はまったく発生せず、完了するまでに1秒もかかりません。

これが十分な情報であることを願っています。なぜこれが発生するのか、そしてどのように解決できるのかについて、私は本当に興味があります。

編集:最初の内部結合を削除すると(最大バージョンをフィルタリングするため)、パフォーマンスの低下がなくなることに注意する必要があります。

4

1 に答える 1

0

プロファイラーがこれらすべてのケースを処理できるはずであることは知っていますが、とにかく質問します...

次のいずれかをプロファイリングしようとしましたか:

  • 内部選択を CTE に変換しますか?
  WITH CTE_Versions AS (
      SELECT DataID, MAX(VersionNum) as mVersion 
      FROM t1
      GROUP BY DataID 
  )
  SELECT DISTINCT t1.status AS Status
  FROM t1
  JOIN CTE_Versions AS b
      ON t1.DataID = b.DataID 
      AND t1.VersionNum = b.mVersion
  JOIN table2
      ON t1.table2ID = table2.ID
  WHERE table2.field = @parameter
  • ロックのヒントを追加しますか?
  SELECT DISTINCT t1.status AS Status
  FROM t1 with (nolock)
  JOIN (
          SELECT DataID, MAX(VersionNum) as mVersion 
          FROM t1 with (nolock)
          GROUP BY DataID 
  ) AS b
      ON t1.DataID = b.DataID 
      AND t1.VersionNum = b.mVersion
  JOIN table2 with (nolock)
      ON t1.table2ID = table2.ID
  WHERE table2.field = @parameter
  • パラメータを結合に移動しますか? (@ X-Zeroのコメントによる)
  SELECT DISTINCT t1.status AS Status
  FROM t1
  JOIN (
          SELECT DataID, MAX(VersionNum) as mVersion 
          FROM t1
          GROUP BY DataID 
  ) AS b
      ON  t1.DataID = b.DataID 
      AND t1.VersionNum = b.mVersion
  JOIN table2
      ON  t1.table2ID = table2.ID
      AND table2.field = @parameter

これらの 3 つ (またはその組み合わせ) がどのようになるかを知りたいです。

于 2012-09-14T09:17:02.767 に答える