Problema de consulta SQL Al actualizar desde SQL Server 2000 a SQL Server 2008 R2
-
26-09-2019 - |
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
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