und*_*ned 9 sql sql-server database-performance query-performance sql-server-2014
可能的解释在评论中
在SQL Server 2014企业版(64位)中 - 我试图从视图中读取.标准查询只包含一个ORDER BY
和这样的OFFSET-FETCH
子句.
方法1
SELECT
*
FROM Metadata
ORDER BY
AgeInHours ASC,
RankingPoint DESC,
PublishDate DESC
OFFSET 150000 ROWS
FETCH NEXT 40 ROWS ONLY
Run Code Online (Sandbox Code Playgroud)
但是,这个相当简单的查询比以下返回相同结果的查询执行快9倍(在跳过大量行(如150k)时显而易见).
在这种情况下,我首先读取主键,然后将其用作WHERE...IN
函数的参数
方法2
SELECT
*
FROM Metadata
WHERE NewsId IN (
SELECT
NewsId
FROM Metadata
ORDER BY
AgeInHours ASC,
RankingPoint DESC,
PublishDate DESC
OFFSET 150000 ROWS
FETCH NEXT 40 ROWS ONLY
)
ORDER BY
AgeInHours ASC,
RankingPoint DESC,
PublishDate DESC
Run Code Online (Sandbox Code Playgroud)
这两个基准标记显示了这种差异
(40 row(s) affected)
SQL Server Execution Times:
CPU time = 14748 ms, elapsed time = 3329 ms.
(40 row(s) affected)
SQL Server Execution Times:
CPU time = 3828 ms, elapsed time = 469 ms.
Run Code Online (Sandbox Code Playgroud)
我在主键上有索引,PubilshDate
它们的碎片非常低.我还尝试对数据库表运行类似的查询,但在每种情况下,第二种方法都会产生很大的性能提升.我也在SQL Server 2012上测试了这个.
有人可以解释发生了什么吗?
架构
方法1:执行计划
方法2:执行计划(左侧部分)
方法2:执行计划(右侧部分)
小智 0
当您执行查询时,引擎会查找可用于获得最佳性能的索引。您的方法 1 是使用不包含 SELECT 语句中所有列的索引,这会导致查询计划中的键查找,根据我的经验,在 SELECT 语句中仅使用索引列总是会获得较低的性能。
如果为所有列创建索引AgeInHours, RankingPoint, PublishDate
并包含所有列(建议仅用于测试目的),您可以看到差异。
对于第二种方法,如果您使用 CTE,然后使用 IN 进行 JOIN 而不是 WHERE,或者如果您有数百万行,则使用带有索引的临时表,您甚至可以获得更好的性能。
归档时间: |
|
查看次数: |
418 次 |
最近记录: |