Problema de consulta SQL ao atualizar do SQL Server 2000 para o SQL Server 2008 R2
-
26-09-2019 - |
Pergunta
Atualmente, estou atualizando um servidor de banco de dados do SQL Server 2000 para o SQL Server 2008 R2. Uma das minhas consultas costumava levar menos de um segundo para correr e agora leva mais de 3 minutos (funcionando em uma máquina mais rápida).
Acho que localizei onde está dando errado, mas não por que está dando errado. Alguém poderia explicar qual é o problema e como eu poderia resolvê -lo?
O código resumido é o seguinte:
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
)
Eu acredito que a questão está localizada no "Txn.TransactionId é nulo ou" linha. Se eu remover essa condição, ela é tão rápida quanto costumava (menos de um segundo) e retornar todos os registros menos as 3 linhas que essa afirmação teria incluída. Se eu remover a segunda parte da declaração, ele retornará as 3 linhas que eu esperaria em menos de um segundo.
Alguém poderia me apontar na direção correta de por que isso está acontecendo e quando essa mudança ocorreu?
Muito obrigado antecipadamente
Jonathan
Aceitei a solução de Alex e incluí a nova versão do código. Parece que encontramos 0,1% das consultas que o novo otimizador de consulta funciona mais lentamente.
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
Solução
Tente reestruturar a consulta usando um cte e 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