我目前正在将数据库服务器从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.transactionId为null或” 线。如果我删除此条件,它的运行速度与过去(少于一秒钟)的快速运行,并返回所有记录减去该语句所包含的3行。如果我删除或语句的第二部分,它将返回我期望不到一秒钟的3行。

有人可以指出我为什么会发生这种情况以及发生这种变化时正确的方向?

提前谢谢了

乔纳森


我已经接受了Alex的解决方案,并包括了代码的新版本。似乎我们发现新查询优化器运行速度较慢的疑问中有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
有帮助吗?

解决方案

尝试使用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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top