12

私のgoogle-fuとso-fuはここで失敗しているので、質問した方がいいかもしれません.

複数の結合を含む多くのクエリがあります。

1 つのクエリ内で、ヘッダー/アイテム/詳細を結合し、これらのレコードのさまざまな情報を検索します。

参加するときは、物事がどのように関連しているかを整理するようにしています。例: 私のヘッダーには 2 つのルックアップ テーブルがあるので、アイテム テーブルに結合する前にそれらに結合します。

あれは正しいですか?

ルックアップ テーブルの前に、より大きなテーブルに結合する方がよいでしょうか? それともその逆?

loop小さなテーブルに参加するときはヒントを使用し、mergeopenrowset に参加するときはヒントを使用する必要がありますか?

答えは「場合による」と思いますが、効果的かつ効率的に参加するための一般的なガイドラインがあれば非常に役立ちます。ありがとう!

4

2 に答える 2

12

編集:あなたの質問(およびKirk Wollの)コメントに基づいて、結合の順序は美的であり、結果の実行プランに直接影響しないことを理解する必要があります。クエリオプティマイザは、最も効率的な順序で結合を実行し、ほとんどの場合、ヒントを必要とせずに適切な結合操作を使用します。

結合順序の美学に関しては、これは少し主観的ですが、クエリを読むときに論理的に意味のある順序でテーブルを結合すると思います... @ HeaderIdで開始する場合は、そのテーブルから開始します、JOIN次に子テーブルへ:

FROM
    Header h
    JOIN Items i ON h.HeaderId = i.HeaderId
    JOIN Details d ON i.ItemId = d.ItemId
WHERE
    h.HeaderId = @HeaderId

ただし、@ DetailIdでクエリを開始した場合は、逆の順序で参加します。

FROM
    Details d
    JOIN Items i ON d.ItemId = i.ItemId
    JOIN Header h ON i.HeaderId = h.HeaderId
WHERE
    d.DetailId = @DetailId

しかし、それは主観的なものであり、私の個人的な好みです。

sを含め始めると、主観的ではなくなりますOUTER JOIN... sを回避するようにクエリを構造化してRIGHT OUTER JOIN、代わりにLEFT OUTER JOIN'sを使用してください。

デフォルトでは結合ヒントを使用しないでください...実際、それらを使用することはほとんどありません。クエリオプティマイザは、最適な実行プランを選択するのに非常に優れています。計画を改善するために結合のヒントを提供する必要があるインスタンスは1つしかありませんでした...その時点でクエリが実行されていたサーバーでは大幅に役立ちましたが、データベースが別のサーバーに移行されたときは、私の参加ヒントはクエリのパフォーマンスを破壊しました。したがって、繰り返しになりますが、通常、結合のヒントを提供することはお勧めできません。

于 2012-03-29T14:41:26.373 に答える
0

順序はおおむね [1] 審美的ですが、混乱を避けるために、表の順序と ON 条件の用語の両方に規則を設けておくと便利だと思います。

クエリ ヒントは例外的な場合にのみ使用できます。クエリ ヒントを使用する必要がある状況 (通常は同時実行数の減少によりパフォーマンスが犠牲になる) がある場合は、常に問題を解決するためのより確実な方法を見つけるようにしてください。

[1] 順序が重要なケースを 1 つ知っています。

CREATE TABLE A (
  id int IDENTITY PRIMARY KEY,
  name varchar
);

CREATE TABLE B (
  id int IDENTITY PRIMARY KEY,
  a_id int FOREIGN KEY REFERENCES A (id),
  name varchar
);

SELECT *
FROM A
INNER LOOP JOIN B on A.id = B.a_id;

SELECT *
FROM B
INNER LOOP JOIN A on A.id = B.a_id;

最初の選択では 2 つのインデックス スキャンが実行され、2 番目の選択ではスキャンとシークが実行されます。これは、ヒントを避けるもう 1 つの正当な理由です。

于 2012-06-01T13:44:02.963 に答える