2012-04-13 215 views
1

我正在查詢表以選擇最後n條記錄,但保留了順序。對於這一點,我使用下面的查詢這是我從Select Top N Records Ordered by X, But Have Results in Reverse Order有:關於從表中選擇最後n條記錄的性能

WITH Temp 
      AS (SELECT TOP 10 
         [TestID] , 
         UserID , 
         DateSent 
       FROM  [Test] 
       WHERE UserID = @UserID 
       ORDER BY DateSent DESC 
      ) 
    SELECT * 
    FROM Temp 
    ORDER BY DateSent 

即我選擇最後N條記錄,同時保留排序順序。下面是空的腳本創建上述表:

GO 
CREATE TABLE [dbo].[Test] 
    (
     [TestID] [int] IDENTITY(1, 1) 
        NOT NULL , 
     [UserID] [int] NOT NULL , 
     [DateSent] [datetime] NOT NULL , 
     CONSTRAINT [PK_TestID] PRIMARY KEY CLUSTERED ([TestID] ASC) 
     WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
       IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
       ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
    ) 
ON [PRIMARY] 
GO 

CREATE NONCLUSTERED INDEX [IX_Test_UserID_DateSent] ON [dbo].[Test] 
(
    [UserID] ASC, 
    DateSent DESC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
GO 


GO 

INSERT INTO [Test] 
SELECT TOP 100000 ABS(CAST(NEWID() AS BINARY(6)) %10), 
DATEADD(day, DATEDIFF(day, 0, GETDATE()) - 1 - FLOOR(RAND(CAST(NEWID() AS binary(4))) * 365.25 * 90), 0) 
FROM master..spt_values 
GO 

我在上文中創建的表,就可以申請指數,並在其中插入一些虛擬的數據。我執行此查詢來獲取記錄:

DECLARE @UserID INT 
SET @UserID = 1 ; 
WITH Temp 
      AS (SELECT TOP 10 
         [TestID] , 
         UserID , 
         DateSent 
       FROM  [Test] 
       WHERE UserID = @UserID 
       ORDER BY DateSent DESC 
      ) 
    SELECT * 
    FROM Temp 
    ORDER BY DateSent 

下面是運行上面的查詢後的執行計劃:

enter image description here

正如你可以看到指數以下,但對於內部查詢和您可以在索引計劃中看到77%的執行是由排序過程執行的。 我該如何避免這種情況?我應該在這裏應用什麼指數來克服這種情況。

+0

是的的確的。但是,我可以更改我的查詢或創建一些不同的索引來爲這10條記錄應用索引嗎? – 2012-04-13 12:19:18

+0

查看我的回答哪個地址的問題。 – Yuck 2012-04-13 12:21:22

回答

5

消耗77%執行計劃的最左側排序僅適用於您的TOP 10記錄。您可以通過刪除最後ORDER BY驗證這一點:

DECLARE @UserID INT 
SET @UserID = 1 ; 
WITH Temp 
      AS (SELECT TOP 10 
         [TestID] , 
         UserID , 
         DateSent 
       FROM  [Test] 
       WHERE UserID = @UserID 
       ORDER BY DateSent DESC 
      ) 
    SELECT * 
    FROM Temp 
    --ORDER BY DateSent 

應當提及的是,在一個計劃中的所有運營商必須爲100%。如果您最便宜的操作(即僅分類10條記錄)消耗大部分執行時間,那麼我會說您狀態良好。

enter image description here

+0

我想要克服那個Sort Operator也可能爲該操作符應用一些索引呢? – 2012-04-13 12:27:16

+0

@RockySingh問題是你不能將所有操作減少到0%。這項工作必須在某個地方完成。由於你的排序是在物化表(CTE)上,我不知道索引是否可以使用。即使如此,它僅適用於** 10行**。這會真正提高執行時間多少? – Yuck 2012-04-13 12:32:59

+0

其實nubmers總是100%。它本身並不是「昂貴的」,而是「在那裏花費了多少時間」。如果你減少索引尋求 - 你認爲100%去哪裏 - 在別的地方。它必須足夠快,花時間花在時間上必須合理。它在這裏 - 通過索引訪問數據。但這些數字總是最終爲100--這是相對的重量,而不是絕對的。 – TomTom 2012-04-13 13:23:56

相關問題