2011-11-09 16 views
2

MSSQLを使用してクエリを実行すると、計算されたテーブルから単一の列を取得し、結果セットに接続する最も効率的な方法があります。ページ分割された結果セット内の選択サブクエリまたは左外部結合が速くなる

テーブル:mytable.col1mytable = 20K行のインデックス、othertable = 30K行、インデックスなし

othertable.col1上のインラインクエリ -

SELECT * FROM (
    SELECT col1, col2, col3, 
    col4 = (SELECT min(col5) FROM othertable o WHERE m.col1 = o.col1) 
    row = ROW_NUMBER() OVER(ORDER BY somerow) 
    FROM mytable m 
) as paged 
WHERE row BETWEEN 1 AND 25 

select文でクエリを実行し、クエリに参加 - テーブルを計算テーブルに結合する

SELECT * FROM (
    SELECT col1, col2, col3, o2.col5again 
    row = ROW_NUMBER() OVER(ORDER BY somerow) 
    FROM mytable m 
    JOIN (SELECT col1, min(col5) as col5again FROM othertable o GROUP BY col1) as o2 ON o2.col1 = m.col1 
) as paged 
WHERE row BETWEEN 1 AND 25 

私の直感は速かったJOINでした。ただし、インラインクエリのテストでは平均7秒で完了しますが、MSSQLスタジオで実行された場合は30秒を超えるクエリが残ります。

  1. インライン選択クエリを使用して実際に単一の列を挿入する最良の方法はありますか?
  2. インラインSELECT()文を実行するまで最適化されたクエリは、結果がページされるまで実行されますが、これは実行時間の違いを説明しますか? FYI

:私の具体的な例では、othertable.col1にインデックスを追加し、それが0にクエリ時間を減少するが、この質問は、SELECT対のJOIN()が優れているかどうかに多くを焦点を当てています。

+0

これらはどちらもコンパイルされますか?一番内側のクエリに 'FROM'がありません。 – ThomasMcLeod

+0

'FROM'を追加しました。この正確なクエリをテストしていませんでした。実際の例からこれを削除しています。 – Nucleon

+0

最良の発見方法は、 'set statistics time on 'で両方のクエリを実行して、その持続時間を表示することです。トレースを実行して期間を見ることもできます。 –

答えて

5

パフォーマンスチューニングは、計画がどのように作成されたか、計画の各要素が何をするのか、そしてより効率的な方法を選択する方法を理解することが含まれます。

索引を紛失すると、スキャン(過剰読み取り)が発生します。索引が多すぎると、DUI(削除、更新、挿入)が遅くなります。古くなったり欠落したりすると、誤った結合アルゴリズムが使用されたり、行数が不正確に推定されたりします(ページングにつながる可能性があります)。

両方のクエリを同じウィンドウで実行し、実際の実行計画を含めます。これは計画を分割し、どちらがより高価であるかを伝えます。インデックスヒントがありません。計画を読み進めるにつれて、クエリのパフォーマンスを向上させる方法を学びます。

関連する問題