SQL Server 2012 row_number ASC DESC性能

DBO*_*DBO 4 sql-server row-number sql-server-2012

在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
Run Code Online (Sandbox Code Playgroud)
  • 当我使用ORDER BY SequentialNumber ASC它需要400毫秒
  • 当我ORDER BY DESC在row_number函数中使用它只需要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
Run Code Online (Sandbox Code Playgroud)

Mik*_*son 6

查询计划并不完全相同.

选择"索引扫描"运算符.

在此输入图像描述

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

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

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

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

  • 哦,我再次阅读了问题和答案.你是对的,stop = 0的行的分布是个问题. (2认同)