【问题标题】:SQL Server 2012 row_number ASC DESC performanceSQL Server 2012 row_number ASC DESC 性能
【发布时间】:2014-10-17 10:35:40
【问题描述】:

在 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 毫秒

(这是在测试环境中,在生产环境中是 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

【问题讨论】:

  • 没有“SQL Server 2012 R2”版本 - 将其更正为“SQL Server 2012”...
  • 是的,抱歉,是 2012 SP2
  • 两张表之间是否存在FOREIGN KEY约束?

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


【解决方案1】:

查询计划并不完全相同。

选择索引扫描运算符。

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

当您升序时,扫描方向为正向,而当您降序时,扫描方向为后退。

之所以存在行数差异,是因为在索引中向后扫描时只需 53 行即可找到 30 行,而在索引中向前扫描时需要 117k 行才能找到 30 个匹配行。

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

【讨论】:

  • 感谢米凯尔。很明显差别不大,一个是索引扫描的扫描方向,但是其他对数据库的宏操作都是一样的。此查询中没有 order by,因为示例取自更复杂的查询,并且不会影响工作的其余部分
  • @DBO 是的。在找到您在 top 子句中指定的 30 行之前必须读取多少行是一个问题。当查询返回 30 行时,scan 运算符停止扫描,并且向前扫描时比向后扫描时更快。
  • 问题和奇怪的是我的查询降序更快!并且索引列是升序的
  • @DBO 我读错了。然而,这根本不重要。我会更新答案。可以使用升序索引进行向后扫描。
  • 哦,我又看了一遍问题和答案。你是对的,stop=0 的行分布是问题。
猜你喜欢
  • 2012-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-16
  • 1970-01-01
  • 1970-01-01
  • 2015-12-22
相关资源
最近更新 更多