SQL Server 2012 row_number ASC DESC性能

时间:2014-10-17 10:35:41

标签: sql-server sql-server-2012 row-number

在SQL Server 2012版本11.0.5058中,我有一个像这样的查询

SELECT TOP 30 
    row_number() OVER (ORDER BY SequentialNumber ASC) AS [row_number], 
    o.Oid, StopAzioni 
FROM 
    tmpTestPerf O 
INNER JOIN
    Stati s on O.Stato = s.Oid
WHERE 
    StopAzioni = 0
  • 当我使用ORDER BY SequentialNumber ASC时需要400毫秒
  • 当我在row_number函数中使用ORDER BY DESC时,它只需2 ms

(这是在测试环境中,在生产中它是7000,7秒对15毫秒!)

分析执行计划,我发现两个查询都是一样的。有趣的区别在于它在较慢的情况下适用于按stopazioni = 0条件过滤的所有行,117k行

速度越快,它只使用53行

tmpTestPerf查询上有一个主键,序列号列上有索引的ASC键。

如何解释?

的问候。 丹尼尔

这是tmpTestPerfQuery和Stati查询的脚本及其索引

CREATE TABLE [dbo].[tmpTestPerf]
(
    [Oid] [uniqueidentifier] NOT NULL,
    [SequentialNumber] [bigint] NOT NULL,
    [Anagrafica] [uniqueidentifier] NULL,
    [Stato] [uniqueidentifier] NULL,

    CONSTRAINT [PK_tmpTestPerf] 
      PRIMARY KEY CLUSTERED ([Oid] ASC)
)

CREATE NONCLUSTERED INDEX [IX_2] 
   ON [dbo].[tmpTestPerf]([SequentialNumber] ASC)

CREATE TABLE [dbo].[Stati]
(
    [Oid] [uniqueidentifier] ROWGUIDCOL  NOT NULL,
    [Descrizione] [nvarchar](100) NULL,
    [StopAzioni] [bit] NOT NULL

    CONSTRAINT [PK_Stati] 
      PRIMARY KEY CLUSTERED ([Oid] ASC)
) ON [PRIMARY]

CREATE NONCLUSTERED INDEX [iStopAzioni_Stati] 
   ON [dbo].[Stati]([StopAzioni] ASC)
GO

1 个答案:

答案 0 :(得分:6)

查询计划并不完全相同。

选择“索引扫描”操作符。

enter image description here

按F4查看属性并查看扫描方向。

当您升序时,扫描方向为前进,当您下单时,它是后退。

存在行数的差异,因为向后扫描时只需要53行就能找到30行,并且需要117k行才能找到在索引中向前扫描的30个匹配行。

<子> 请注意,如果主查询中没有order by子句,则无法保证从查询中获得30行。在这种情况下,它恰好是前三十个或后三十个,具体取决于row_number()中使用的顺序。