sql - SELECT MAX() 太慢 - 有其他选择吗?

标签 sql sql-server timeout max

我继承了一个基于 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;

SQL Fiddle .

这在语义上与 OP 的查询不同,OP 会在 StatusTime 冲突时返回多行,我只是猜测这就是所需的内容(“此 BItem 的最新 BData”)。

关于sql - SELECT MAX() 太慢 - 有其他选择吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20351358/

相关文章:

linux - Curl 和 Wget 返回响应,浏览器超时

asp.net - 有没有办法让executionTimeout在调试时生效?

linux - 如何查看进程是否被杀死?

sql - 如何多次执行存储过程

sql - 系列生成函数和间隔?

sql-server - INSERT INTO SELECT 使用 UNION 的奇怪顺序

sql-server - 将数字转换为数字数据类型时出现算术溢出错误。英孚核心

sql-server - 经典 ASP - 使用一个连接进行多个查询?

mysql - 问题:未在VBA上定义有关套接字的变量

java - 有点混淆 SQL 和 Tomcat