我继承了一个基于 SQL Server 的应用程序,它有一个包含以下内容的存储过程,但它超时了。我相信我已经将问题隔离到 SELECT MAX() 部分,但我不知道如何使用替代方案,例如 ROW_NUMBER() OVER( PARTITION BY...
有人有什么想法吗?
这是“有问题的”代码:
SELECT BData.*, B.*
FROM BData
INNER JOIN
(
SELECT MAX( BData.StatusTime ) AS MaxDate, BData.BID
FROM BData
GROUP BY BData.BID
) qryMaxDates
ON ( BData.BID = qryMaxDates.BID ) AND ( BData.StatusTime = qryMaxDates.MaxDate )
INNER JOIN BItems B ON B.InternalID = qryMaxDates.BID
WHERE B.ICID = 2
ORDER BY BData.StatusTime DESC;
提前致谢。
最佳答案
SQL 性能问题很少通过重写查询来解决。无论如何,编译器已经知道如何重写它。问题始终是索引。要有效地获取 MAX(StatusTime ) ... GROUP BY BID
,您需要在 BData(BID, StatusTime)
上建立索引。为了有效查找 WHERE B.ICID = 2
,您需要在 BItems.ICID
上建立索引。
查询也可能表示为相关的 APPLY ,因为看起来这才是真正想要的:
SELECT D.*, B.*
FROM BItems B
CROSS APPLY
(
SELECT TOP(1) *
FROM BData
WHERE B.InternalID = BData.BID
ORDER BY StatusTime DESC
) AS D
WHERE B.ICID = 2
ORDER BY D.StatusTime DESC;
这在语义上与 OP 的查询不同,OP 会在 StatusTime 冲突时返回多行,我只是猜测这就是所需的内容(“此 BItem 的最新 BData”)。
关于sql - SELECT MAX() 太慢 - 有其他选择吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20351358/