I am currently upgrading a database server from SQL Server 2000 to SQL Server 2008 R2. One of my queries used to take under a second to run and now takes in excess of 3 minutes (running on faster a faster machine).
I think I have located where it is going wrong but not why it is going wrong. Could somebody explain what the problem is and how I might resolve it?
The abridged code is as follows:
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
)
I believe the issue is located on the "txn.transactionid IS NULL OR" line. If I remove this condition it runs as fast as it used to (less than a second) and returns all the records minus the 3 rows that that statement would have included. If I remove the second part of the OR statement it returns the 3 rows that I would expect in less than a second.
Could anybody point me in the correct direction as to why this is happening and when this change occured?
Many thanks in advance
Jona开发者_运维知识库than
I have accepted Alex's solution and included the new version of the code. It seems that we have found 0.1% of queries that the new query optimiser runs slower.
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
Try restructuring the query using a CTE and 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
精彩评论