Frage

Derzeit aktualisiere ich einen Datenbankserver von SQL Server 2000 auf SQL Server 2008 R2. Eine meiner Anfragen nahm früher unter einer Sekunde Zeit, um zu laufen, und nimmt jetzt mehr als 3 Minuten (schneller auf einer schnelleren Maschine).

Ich glaube, ich habe dort dort gefunden, wo es schief geht, aber nicht, warum es schief geht. Könnte jemand erklären, was das Problem ist und wie ich es lösen könnte?

Der gekürzte Code lautet wie folgt:

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
  )

Ich glaube, das Problem befindet sich auf der "txn.transactionid ist null oder" Linie. Wenn ich diesen Zustand entferne, läuft sie so schnell wie früher (weniger als eine Sekunde) und gibt alle Datensätze abzüglich der 3 Zeilen zurück, die diese Anweisung enthalten hätte. Wenn ich den zweiten Teil der oder Anweisung entferne, gibt es die 3 Zeilen zurück, die ich in weniger als einer Sekunde erwarten würde.

Könnte mich jemand in die richtige Richtung verweisen, warum dies geschieht und wann diese Änderung aufgetreten ist?

Vielen Dank im Voraus

Jonathan


Ich habe die Lösung von Alex akzeptiert und die neue Version des Codes aufgenommen. Es scheint, dass wir 0,1% der Abfragen gefunden haben, die der neue Abfrage -Optimierer langsamer läuft.

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
War es hilfreich?

Lösung

Versuchen Sie, die Abfrage mit einem CTE und row_number umzustrukturieren ...

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top