私のオフィスには、見苦しいクエリがありますが、運用環境と開発環境(それぞれ20秒と4秒)でかなりうまく実行されます。ただし、テスト環境では4時間以上かかります。SQL2005(+最新のパッチ)は、本番環境および開発環境で実行されています。SQL2008R2はテストで実行されています。
クエリプランを確認したところ、SQL2008R2はリンクサーバーから返された行を格納するために、テーブルスプール(レイジースプール)を介してTempDBを使用していることがわかります。次のステップは、クエリの96.3%を消費しているネストされたループ(左反準結合)を示しています。2つのオペレーター間の境界線は5,398MBです。
SQL 2005のクエリプランでは、tempdbの使用とLeft Anti Semi Joinの使用は示されていません。
以下はサニタイズされたコードであり、実行計画は2005年の計画を上に、2008R2は下を計画しています。
劇的なスローダウンと変化の原因は何ですか?別の実行プランが表示されることを期待していたので、気になりません。クエリ時間の劇的なスローダウンが私を悩ませています。
2008R2バージョンはtempdbを使用しているため、基盤となるハードウェアを確認する必要がありますか?その使用を最適化する方法を確認する必要がありますか?
クエリを記述するより良い方法はありますか?
助けてくれてありがとう。
INSERT INTO Table1_GroupLock (iGroupID, dLockedDate)
SELECT
Table1.iGroupID,
GETDATE()
FROM Table1
WHERE
NOT EXISTS (
SELECT 1
FROM LinkedServer.Database.Table2 Alias2
WHERE
(
Alias2.FirstName + Alias2.LastName = dbo.fnRemoveNonLetter(Table1.FullName)
AND NOT dbo.fnRemoveNonLetter(Table1.FullName) IS NULL
AND NOT Alias2.FirstName IS NULL
AND NOT Alias2.LastName IS NULL
) OR (
Alias2.FamilyName = dbo.fnRemoveNonLetter(Table1.FamilyName)
AND Alias2.Child1Name = dbo.fnRemoveNonLetter(Table1.Child1Name)
AND NOT dbo.fnRemoveNonLetter(Table1.FamilyName) IS NULL
AND NOT dbo.fnRemoveNonLetter(Table1.Child1Name) IS NULL
AND NOT Alias2.Familyname IS NULL
AND NOT Alias2.Child1Name IS NULL
) OR (
Alias2.StepFamilyName = dbo.fnRemoveNonLetter(Table1.StepFamilyName)
AND Alias2.StepFamilyNameChild1 = dbo.fnRemoveNonLetter(Table1.StepFamilyNameChild2)
AND NOT Alias2.StepFamilyName IS NULL
AND NOT Alias2.StepFamilyNameChild1 IS NULL
AND NOT dbo.fnRemoveNonLetter(Table1.StepFamilyName) IS NULL
AND NOT dbo.fnRemoveNonLetter(Table1.StepFamilyNameChild2) IS NULL
)
) AND NOT EXISTS (
SELECT 1
FROM Table3
INNER JOIN Table4
ON Table4.FirstNameType = Table3.FirstNameType
INNER JOIN table5
ON table5.LastNameType = Table3.LastNameType
WHERE
Table3.iGroupID = Table1.iGroupID
AND Table3.bIsClosed = 0
AND Table4.sNameTypeConstant = 'new_lastname'
AND table5.sFirstNameConstant = 'new_firstname'
)
::編集:: 別のSQL2005インスタンスからクエリを実行しました。「良いもの」とほぼ同じ実行プランです。2008R2インスタンスから2008R2インスタンスよりも、2つの2005バージョンが2008R2リンクサーバーに対してどのように実行されるかはまだわかりません。
コードがいくつかの作業を使用する可能性があることは否定しませんが、それが問題のコードである場合、すべてのトライアルで同じようなexec計画を表示しませんか?SQLのバージョンに関係なく?
::編集:: SP1とCU3を2008R2インスタンスの両方に適用しましたが、まだサイコロはありません。リンクサーバーにコロケーションを具体的に設定しましたが、サイコロはありません。私は特に、ユーザーacctの権限を、サイコロではなく、両方のインスタンスでsysadminに設定しています。私はSQLサーバー2008の内部とトラブルシューティングも覚えています。これをいくつか追跡することができるかどうかを確認します。
ヘルプとヒントをありがとうございました。
::編集:: リンクサーバーにさまざまな権限の変更を行いました。SQLログイン、ドメインログインを使用したり、ユーザーを偽装したり、「このセキュリティコンテキストを使用して作成する」オプションを使用したりしました。サーバーでsysadmin権限を持つリンクサーバーの両側にユーザーを作成しました。アイデアが足りません。
SQL2005がSQL2008R2と大きく異なるクエリを実行している理由を知りたいのですが。クエリが悪かった場合、SQL2005とSQL2008R2の両方で4時間以上の実行時間が表示されます。