Problème de requête SQL lors de la mise à niveau de SQL Server 2000 à SQL Server 2008 R2
-
26-09-2019 - |
Question
Je mets actuellement à la mise à niveau d'un serveur de base de données de SQL Server 2000 à SQL Server 2008 R2. Une de mes requêtes prenait moins d'une seconde pour fonctionner et prend maintenant plus de 3 minutes (en cours d'exécution plus vite une machine plus rapide).
Je pense que j'ai situé où ça va, mais pas pourquoi ça va mal. Quelqu'un pourrait-il expliquer quel est le problème et comment je pourrais le résoudre?
Le code abrégé est le suivant:
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
)
Je crois que le problème est situé sur le "Txn.TransactionId est nul ou" ligne. Si je retire cette condition, il fonctionne aussi vite qu'auparavant (moins d'une seconde) et renvoie tous les enregistrements moins les 3 lignes que cette déclaration aurait incluses. Si je supprime la deuxième partie de l'énoncé ou, il renvoie les 3 lignes que j'attendrais en moins d'une seconde.
Quelqu'un pourrait-il me pointer dans la bonne direction pour savoir pourquoi cela se produit et quand ce changement s'est produit?
Merci d'avance
Jonathan
J'ai accepté la solution d'Alex et inclus la nouvelle version du code. Il semble que nous ayons trouvé 0,1% des requêtes que le nouvel Optimiser de requêtes fonctionne plus lentement.
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
La solution
Essayez de restructurer la requête à l'aide d'un CTE et ROW_NUMBER ...
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