2014-10-17 111 views
4

在SQL Server 2012版本11.0.5058我喜欢这个SQL Server 2012的ROW_NUMBER ASC DESC性能

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毫秒
  • 当我使用ORDER BY DESC在ROW_NUMBER函数只需要2毫秒

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

分析执行计划,我发现这两个查询都是一样的。有趣的区别是,在较慢它与由stopazioni = 0条件过滤所有行,117K行

在它仅使用53行

上有tmpTestPerf查询和索引的主键快序列号列上的ASC密钥。

如何解释?

问候。 丹尼尔

这是tmpTestPerfQuery和为static查询的脚本与他们的指标

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 
+0

没有 “的SQL Server 2012 R2” 版本 - 修正它只是 “SQL Server 2012的” ... – 2014-10-17 10:41:45

+0

是的,对不起,是2012 SP2 – DBO 2014-10-17 13:45:19

+0

是否有2个表之间的'外国KEY'约束? – 2014-10-22 10:01:25

回答

6

查询计划并不完全相同。

选择索引扫描运算符。

enter image description here

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

当您升序扫描方向为向前时,并且当您降序时,它向后。

行数的不同之处在于,因为在向后扫描时只需要53行来查找30行,并且需要117k行才能找到30个匹配的行,以便在索引中向前扫描。

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

+0

感谢Mikael。 显然没有什么区别,一个是索引扫描的扫描方向,但对数据库所做的其余宏操作是相同的。 在此查询中没有排序,因为从更复杂的查询中取得了一个示例,并且它不影响其余的作业。 – DBO 2014-10-17 13:31:50

+1

@DBO是的。在查找您在顶部子句中指定的30之前,必须读取多少行。当查询返回了30行时,扫描操作员停止扫描,并且在向前扫描时向后扫描时发生的速度更快。 – 2014-10-17 13:40:24

+0

这个问题和奇怪的是,我的查询是降速更快! 和索引列是在升序 – DBO 2014-10-17 13:47:15