web-dev-qa-db-ja.com

データベース間のクエリが遅い

同じSQLサーバー上に2つのデータベース/カタログがあり、両方にアクセスできるSQLユーザーがいます。

Database01の照合順序はDanish_Norwegian_CI_ASです

Database02の照合順序はSQL_Latin1_General_CP1_CI_ASです

「Database02」で2つのビューを照会する必要があります。クエリは基本的に

SELECT * FROM View01 -- (resulting in 43 rows)
SELECT * FROM View02 -- (resulting in 2000 rows)

2つのビューは(控えめに言っても)かなり複雑であり、それらを変更するアクセス権がありません。

SQLサーバーにログオンし、「デフォルトのカタログ」として「Database02」を指定すると、クエリはそれぞれ「0.001」と30秒で応答します。

ただし、SQL Serverにログオンし、「Database01」を「デフォルトカタログ」として指定すると、最初のクエリは30秒で実行されますが、2番目のクエリは600秒後にタイムアウトします。

Database01で実行されるクエリは次のようになります。

SELECT * FROM Database02.View01
SELECT * FROM Database02.View02

誰でもこの動作を説明できますか?データベース間の結合を行うつもりはないので、異なる照合順序が問題になることはないと思います。

遅いクエリ: https://www.brentozar.com/pastetheplan/?id=BJgyIUhrG

高速クエリ: https://www.brentozar.com/pastetheplan/?id=S1-BUIhSG

PARAMETERIZATIONは両方のデータベースで「シンプル」です。

私はあなたの計画を見て、この違いの原因を見つけました:

_compatibility level_ 100を使用してデータベースで低速プランを取得します(プランを参照:CardinalityEstimationModelVersion = "70"つまり古いカーディナリティエスティメータが使用されます)。

SQL Server 2014の新しいカーディナリティエスティメータを使用して適切な計画が生成されます:CardinalityEstimationModelVersion = "120"

見積もりが間違っている正確な述語を見つけるには、ビューテキストで質問を更新する必要がありますが、スロープランのカーディナリティでは、OMInternalOrganizationとの結合が過小評価されているため、NLが選択されましたこのテーブルの_Hash Join_が表示される高速プラン。この結合低速プランから開始すると、他の多くの_Nested Loops_が表示されますが、_Hash Join_の方が高速で、高速プランで使用されます。

データベースが_compatibility level_ 100のままになっている理由はわかりません。他のクエリは古いカーディナリティエスティメータを使用するとパフォーマンスが向上する可能性があるため、そのデータベースのグローバルに互換性レベルを120に変更する代わりに、ローカルクエリオプションを使用することをお勧めします:OPTION (QUERYTRACEON 2312)は、その「古いスタイルの」データベースでも新しいカーディナリティエスティメータを使用するようにクエリを強制します。

カーディナリティ推定の詳細はこちら: カーディナリティ推定(SQL Server)

そしてここ: SQL Server 2014 Cardinality Estimatorを使用したクエリプランの最適化

4
sepupic