我有这个简单的查询,希望非常明显。
SELECT ROW_NUMBER() OVER (PARTITION BY Price_Id ORDER BY date DESC) r, * FROM Samples
我的问题是我有超过80000条记录,执行该查询大约需要3秒钟。我的问题是,我能做些什么来提高性能?
我正在考虑一个索引,并想出了像
这样的东西CREATE INDEX IX_Samples_Date ON Samples (Date DESC)
但我不得不承认我之前从未使用过索引,而且我上面的尝试都没有用。
答案 0 :(得分:3)
您需要POC索引。请查看SQL Server 2012: How to Write T-SQL Window Functions, Part 3的索引指南部分。
因此,在您的情况下,您需要将Price_Id
作为索引中的第一列。
create index IX_Samples_POC on dbo.Samples(Price_Id, date desc);
但即使有了索引,也无法保证SQL Server会使用它。您正在查询所有行和所有列,因此您可能无论如何都会进行聚簇索引扫描或表扫描,因为您可能没有所有索引中包含的其他列(自动包含群集密钥)。
根据表结构的样子,如果在派生表中使用row_number
,则可以使用索引获得更快的计划,并将结果返回到获取其余列的表。 / p>
假设您的主键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;
另一种选择是在索引中包含所需的列。如果您确实需要所有列,可能不是一个好主意。
create index IX_Samples_POC on dbo.Samples(Price_Id, date desc)
include(Col1, Col2);
覆盖索引与不使用索引的主要区别在于SQL Server必须执行一些行才能枚举它们。索引已经提供了那种排序。