Pregunta

Actualmente estoy actualizando un servidor de base de datos desde SQL Server 2000 a SQL Server 2008 R2. Una de mis consultas solía tomar menos de un segundo en correr y ahora toma más de 3 minutos (corriendo más rápido una máquina más rápida).

Creo que he localizado a dónde va mal, pero no por qué va mal. ¿Alguien podría explicar cuál es el problema y cómo podría resolverlo?

El código resumido es el siguiente:

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
  )

Creo que el problema se encuentra en el "Txn.TransactionId es nulo o" línea. Si elimino esta condición, se ejecuta tan rápido como solía (menos de un segundo) y devuelve todos los registros menos las 3 filas que esa declaración habría incluido. Si elimino la segunda parte de la declaración OR, devuelve las 3 filas que esperaría en menos de un segundo.

¿Alguien podría señalarme en la dirección correcta de por qué sucede esto y cuándo ocurrió este cambio?

Muchas gracias de antemano

Jonathan


He aceptado la solución de Alex e incluí la nueva versión del código. Parece que hemos encontrado el 0.1% de las consultas que el nuevo optimizador de consultas funciona más lento.

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
¿Fue útil?

Solución

Intente reestructurar la consulta usando un CTE y 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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top