Domanda

Attualmente sto aggiornando un server di database da SQL Server 2000 a SQL Server 2008 R2. Una delle mie domande era solito passare sotto un secondo per correre e ora dura oltre 3 minuti (correndo su una macchina più veloce).

Penso di aver individuato dove sta andando storto, ma non per questo che va storto. Qualcuno potrebbe spiegare qual è il problema e come potrei risolverlo?

Il codice abbreviato è il seguente:

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
  )

Credo che il problema si trovi sul "txn.transactionid è nullo o" linea. Se rimuovo questa condizione, funziona più velocemente come una volta (meno di un secondo) e restituisce tutti i record meno le 3 righe che tale affermazione avrebbe incluso. Se rimuovo la seconda parte dell'istruzione o restituisce le 3 file che mi aspetterei in meno di un secondo.

Qualcuno potrebbe indicarmi nella direzione corretta sul perché questo sta accadendo e quando si è verificato questo cambiamento?

Molte grazie in anticipo

Jonathan


Ho accettato la soluzione di Alex e ho incluso la nuova versione del codice. Sembra che abbiamo riscontrato lo 0,1% delle domande che il nuovo Optimiser di query corre più 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
È stato utile?

Soluzione

Prova a ristrutturare la query usando un 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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top