SQL -Abfrageproblem beim Upgrade von SQL Server 2000 auf SQL Server 2008 R2
-
26-09-2019 - |
Frage
Derzeit aktualisiere ich einen Datenbankserver von SQL Server 2000 auf SQL Server 2008 R2. Eine meiner Anfragen nahm früher unter einer Sekunde Zeit, um zu laufen, und nimmt jetzt mehr als 3 Minuten (schneller auf einer schnelleren Maschine).
Ich glaube, ich habe dort dort gefunden, wo es schief geht, aber nicht, warum es schief geht. Könnte jemand erklären, was das Problem ist und wie ich es lösen könnte?
Der gekürzte Code lautet wie folgt:
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
)
Ich glaube, das Problem befindet sich auf der "txn.transactionid ist null oder" Linie. Wenn ich diesen Zustand entferne, läuft sie so schnell wie früher (weniger als eine Sekunde) und gibt alle Datensätze abzüglich der 3 Zeilen zurück, die diese Anweisung enthalten hätte. Wenn ich den zweiten Teil der oder Anweisung entferne, gibt es die 3 Zeilen zurück, die ich in weniger als einer Sekunde erwarten würde.
Könnte mich jemand in die richtige Richtung verweisen, warum dies geschieht und wann diese Änderung aufgetreten ist?
Vielen Dank im Voraus
Jonathan
Ich habe die Lösung von Alex akzeptiert und die neue Version des Codes aufgenommen. Es scheint, dass wir 0,1% der Abfragen gefunden haben, die der neue Abfrage -Optimierer langsamer läuft.
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
Lösung
Versuchen Sie, die Abfrage mit einem CTE und row_number umzustrukturieren ...
WITH txn AS (
SELECT registrarId, transactionid, ...
, ROW_NUMBER() OVER (PARTITION BY registrarid ORDER BY transactionid DESC) AS RowNum
FROM [Transaction]
)
SELECT
...
FROM
Registrar reg
JOIN EnabledType et ON et.enabledTypeCode = reg.enabled
LEFT JOIN txn ON txn.registrarId = reg.registrarId
AND txn.RowNum=1