Проблема SQL-запроса при обновлении с SQL Server 2000 до SQL Server 2008 R2 - PullRequest
1 голос
/ 27 октября 2010

В настоящее время я обновляю сервер базы данных с SQL Server 2000 до SQL Server 2008 R2.Один из моих запросов раньше занимал менее секунды, а теперь занимает более 3 минут (работает на более быстрой и более быстрой машине).

Я думаю, что я нашел, где он идет не так, но не почемупошло не так.Может кто-нибудь объяснить, в чем заключается проблема и как я могу ее решить?

Сокращенный код выглядит следующим образом:

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
  )

Я считаю, что проблема находится на "txn.транзакция НЕДЕЙСТВИТЕЛЬНА ИЛИ " строка.Если я уберу это условие, оно будет выполняться так же быстро, как и раньше (менее секунды), и возвращает все записи за вычетом 3 строк, которые включил бы этот оператор.Если я удаляю вторую часть оператора OR, он возвращает 3 строки, которые я ожидал бы менее чем за секунду.

Может ли кто-нибудь указать мне правильное направление относительно того, почему это происходит и когда произошло это изменение?

Большое спасибо заранее

ДжонатанЯ принял решение Алекса и включил новую версию кода.Похоже, что мы обнаружили 0,1% запросов, которые новый оптимизатор запросов работает медленнее.

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

1 Ответ

3 голосов
/ 27 октября 2010

Попробуйте реструктурировать запрос, используя CTE и 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
...