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
Foi útil?

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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top