同じ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)