現在、データベース サーバーを SQL Server 2000 から SQL Server 2008 R2 にアップグレードしています。以前は実行に 1 秒もかからなかったクエリの 1 つが、今では 3 分以上かかります (より高速なマシンで実行すると)。
どこがうまくいかないかは突き止めたと思いますが、なぜうまくいかないのかはわかりません。誰かが問題の内容と、それを解決する方法を説明できますか?
要約されたコードは次のとおりです。
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
...
FROM
Registrar reg
JOIN EnabledType et ON et.enabledTypeCode = reg.enabled
LEFT JOIN [Transaction] txn ON txn.registrarId = reg.registrarId
WHERE
txn.transactionid IS NULL OR
txn.transactionid IN
(
SELECT MAX(transactionid)
FROM [Transaction]
GROUP BY registrarid
)
問題は「txn.transactionid IS NULL OR」行にあると思います。この条件を削除すると、以前と同じくらい速く (1 秒未満) 実行され、すべてのレコードからそのステートメントに含まれる 3 行を差し引いたものが返されます。OR ステートメントの 2 番目の部分を削除すると、予想される 3 行が 1 秒以内に返されます。
なぜこれが起こっているのか、そしてこの変化がいつ起こったのかについて、誰かが私を正しい方向に向けることができますか?
よろしくお願いします
ジョナサン
私は Alex の解決策を受け入れ、新しいバージョンのコードを含めました。新しいクエリ オプティマイザーの実行が遅くなるクエリが 0.1% 見つかったようです。
WITH txn AS (
SELECT registrarId, balance , ROW_NUMBER() OVER (PARTITION BY registrarid ORDER BY transactionid DESC) AS RowNum
FROM [Transaction]
)
SELECT
reg.registrarId,
reg.ianaId,
reg.registrarName,
reg.clientId,
reg.enabled,
ISNULL(txn.balance, 0.00) AS [balance],
reg.alertBalance,
reg.disableBalance,
et.enabledTypeName
FROM
Registrar reg
JOIN EnabledType et
ON et.enabledTypeCode = reg.enabled
LEFT JOIN txn
ON txn.registrarId = reg.registrarId
WHERE
ISNULL(txn.RowNum,1)=1
ORDER BY
registrarName ASC