2014-10-17 109 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