使用日期索引优化ROW_NUMBER()

时间:2014-07-07 10:23:29

标签: tsql

我有这个简单的查询,希望非常明显。

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)

但我不得不承认我之前从未使用过索引,而且我上面的尝试都没有用。

1 个答案:

答案 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必须执行一些行才能枚举它们。索引已经提供了那种排序。