【发布时间】:2018-07-25 09:45:16
【问题描述】:
我有以下疑问:
SELECT *
FROM
(
SELECT *,
ROW_NUMBER() OVER(PARTITION BY Code ORDER BY Price ASC) as RowNum
from Offers) r
where RowNum = 1
Offers 表包含大约 1000 万条记录。但是那里只有大约 4000 个不同的代码。所以我需要为每个代码获取价格最低的行,结果中只有 4000 行。
我在 INCLUDE 语句中的所有其他列的(代码、价格)列上有一个索引。
查询运行 2 分钟。如果我查看执行计划,我会看到 10M 实际行的索引扫描。所以,我猜它会扫描整个索引以获取所需的值。
为什么 MSSQL 做整个索引扫描?是因为子查询需要全部数据吗?如何避免这种扫描?是否有 SQL 提示只处理分区中的第一行?
还有其他方法可以优化此类查询吗?
【问题讨论】:
-
子查询本身是否包含表扫描?
-
@AaronDietz 是的,确实如此。它需要为每一行设置排名,这似乎是合乎逻辑的。也许我希望 MSSQL 优化器做所有事情,这就是“为什么 MSSQL 进行整个索引扫描?”的答案。问题。
-
看来关闭需要 2 分钟。我会寻找其他正在发生的事情。尝试使用 nolock - 通常不是一个好的解决方案,但会指出锁是否是问题所在。对索引进行碎片整理。
-
@Paparazzi 我试过 WITH (NOLOCK) 和 OPTION(RECOMPILE) 但没有帮助
-
offers 表中需要哪些字段?为什么不通过查询代码和价格进行分组,然后返回到代码和价格的报价表中
标签: tsql sql-server-2012 query-performance