この結合ヒントは危険ですか?
-
03-07-2019 - |
質問
同僚から、クエリの実行時間が非常に長いため、いくつかのテーブルのインデックス作成を調べてほしいと頼まれました。1時間以上。
select count(1)
from databaseA.dbo.table1
inner join databaseA.dbo.table2 on (table1.key = table2.key)
inner join databaseB.dbo.table3 on (table1.key = table3.key)
データベースが異なることに注意してください。これはデータベースBから実行されていました
テーブル 1 と 2 は 200 万レコードを超える長さでした。Table3 には 12 件ほどのレコードがありました。
クエリ プランを確認したところ、オプティマイザはテーブル 3 を駆動テーブルとしてテーブル 1 と 2 に対してネスト ループ インデックス シークを実行することを決定しました。
私の最初の仮定は、テーブル 1 と 2 で統計がひどく混乱しているということでしたが、統計を更新する前に、次のように結合ヒントを追加してみました。
select count(1)
from databaseA.dbo.table1
inner HASH join databaseA.dbo.table2 on (table1.key = table2.key)
inner join databaseB.dbo.table3 on (table1.key = table3.key)
結果は 15 秒以内に返されました。
時間がなかったので結果を彼に返しましたが、これが将来問題につながるのではないかと心配しています。
統計の問題を再検討して、そのように問題を解決する必要がありますか?不適切なクエリ プランは、別のデータベースからの結合が原因で発生した可能性がありますか?
あなたの経験に基づいてアイデアを提供してくれる人はいますか?
解決
最初に統計を疑います。
ご承知のとおり、99%のケースでは結合ヒントを避け、絶対に必要であるという証拠がある場合にのみ使用してください。
他のヒント
統計を確認し、最初にテーブルのインデックスを作成します。インデックスヒントは問題を引き起こす可能性があります。テーブル内のデータが変更された場合、オプティマイザーは常にハッシュを使用するように強制するため、より効率的なプランを選択できません。
ネストされたループが最も適切ではないでしょうか?表3の12個のレコードを取得し、表1の12個のレコードと一致し、表2の12個のレコードと一致します。
それ以外の場合、ハッシュ結合は順序付けも強制します。つまり、表1と表2から100万レコードをハッシュし、表3の12レコードに結合します。
両方のプランの統計を確認します。ループ結合は実際にはより効率的ですが、ブロックされたか、ハッシュ結合がキャッシュされたデータを利用していたと思われます。
しかし-はい-一般的に、結合のヒントは最後の手段です。
リンク サーバーを含むクエリの実行速度が遅い場合は、照合順序が関係している可能性があります。背景については、こちらを参照してください。 http://blogs.msdn.com/psssql/archive/2008/02/14/how-it-works-linked-servers-and-collation-compatibility.aspxハッシュ結合ヒントによりソート順序が強制されるため、パフォーマンスが向上します。
オプションを設定する方法は次のとおりです。
EXEC master.dbo.sp_serveroption
@server=N'databaseA',
@optname=N'collation compatible',
@optvalue=N'true'
EXEC master.dbo.sp_serveroption
@server=N'databaseA',
@optname=N'use remote collation',
@optvalue=N'false'
-エドオーデ