【发布时间】:2016-12-31 11:30:13
【问题描述】:
可能的解释在这里in the comment
在 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
但是,这个相当简单的查询的执行速度几乎比返回相同结果的以下查询慢 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
对这两者进行基准测试显示了这种差异
(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.
我在主键PubilshDate 上有索引,它们的碎片非常低。我也尝试对数据库表运行类似的查询,但在每种情况下,第二种方法都会产生巨大的性能提升。我还在 SQL Server 2012 上对此进行了测试。
有人能解释一下是怎么回事吗?
架构
方法 1:执行计划
方法二:执行计划(左)
方法二:执行计划(右图)
【问题讨论】:
-
如果您运行第一种方法并选择only
ID列,会发生什么?我怀疑*星号会减慢查询速度,因为它会强制它扫描整个列。 -
快得多(比方说快 9 倍),因为我认为它只查找索引列 (
Id)。令人费解的是,在第二个查询中,当我使用WHERE-IN子句时,它仍在读取相同数量的数据——但不需要时间。幕后发生了什么? -
能否包含查询计划和表架构?
-
@destination-data 稍后会发布,谢谢。
-
看起来速度变慢是因为排序的数据量很大。第一种方法导致对更宽的行进行排序,其中包含 [NewsItems] 中的所有视图列,而第二种方法仅对 4 列宽的数据集进行排序
标签: sql sql-server sql-server-2014 database-performance query-performance