我有这个简单的查询,希望它是不言自明的。
SELECT ROW_NUMBER() OVER (PARTITION BY Price_Id ORDER BY date DESC) r, * FROM Samples
Run Code Online (Sandbox Code Playgroud)
我的问题是我有超过 80000 条记录,执行该查询需要大约 3 秒。我的问题是我是否可以做些什么来提高性能?
我在想一个索引,并想出了类似的东西
CREATE INDEX IX_Samples_Date ON Samples (Date DESC)
Run Code Online (Sandbox Code Playgroud)
但我不得不承认我以前从未使用过索引,而且我上面的尝试没有奏效。
你需要一个 POC 索引。查看SQL Server 2012的索引指南部分:如何编写 T-SQL 窗口函数,第 3 部分。
因此,在您的情况下,您需要将其Price_Id作为索引中的第一列。
create index IX_Samples_POC on dbo.Samples(Price_Id, date desc);
Run Code Online (Sandbox Code Playgroud)
但即使有索引,也不能保证 SQL Server 会使用它。您正在查询所有行和所有列,因此您可能会获得聚集索引扫描或表扫描,因为您的索引中可能没有包含所有其他列(聚集键是自动包含的)。
根据您的表结构的样子,如果您row_number在派生表中使用索引并将结果连接回您获取其余列的表,您可能会使用索引获得更快的计划。
假设您有一个主键 ID,它也是集群键,这样的事情。
select S.*,
T.r
from Samples as S
inner join (
select ID,
row_number() over(partition by Price_Id
order by date desc) as r
from dbo.Samples
) as T
on S.ID = T.ID;
Run Code Online (Sandbox Code Playgroud)
另一种选择是在索引中包含您需要的列。如果您确实需要所有列,这可能不是一个好主意。
create index IX_Samples_POC on dbo.Samples(Price_Id, date desc)
include(Col1, Col2);
Run Code Online (Sandbox Code Playgroud)
覆盖索引与根本不使用索引之间的主要区别在于 SQL Server 必须对行进行排序才能枚举它们。索引已经提供了这种排序。