2012-04-13 13 views
1

最後のn個のレコードを選択するが、順序は保持するためにテーブルを照会しています。ソート順序を維持しながら、私は最後のn個のレコードを選択していますテーブルから最後の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 

すなわち:このため、私は私がSelect Top N Records Ordered by X, But Have Results in Reverse Orderからもらった次のクエリを使用しています。以下は、上記の表を作成するためのダミーのスクリプトです:私は、テーブルを作成した上

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 

、それにインデックスを適用し、その中のいくつかのダミーデータを挿入します。あなたが見ることができるようにインデックスは次のようしかし、内側のクエリのためとされて

enter image description here

:以下

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 

は、上記のクエリを実行した後、実行計画である:私はレコードを取得するには、このクエリを実行していますインデックス・プランでは、実行の77%がソート・プロセスによって取得されることがわかります。 どうしたらいいですか?この状況を克服するために、私はここでどのインデックスを適用すべきですか?

+0

はい、確かです。しかし、私は自分のクエリを変更したり、その10個のレコードに対してもインデックスを適用するために、いくつかの異なるインデックスを作成できますか? –

+0

その質問に対処する私の答えを見てください。 – Yuck

答えて

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

私はそのソート演算子をあまりにも克服しすぎて、その演算子のインデックスをあまりにも適用しようと考えていましたか? –

+0

@RockySingh重要なことは、すべての操作を0%に減らすことができないことです。仕事はどこかで行われなければならない。あなたのソートはマテリアライズド・テーブル(CTE)上にあるので、インデックスを使用できるかどうかはわかりません。それでも、** 10行**のためだけです。どのくらい実際に実行時間を改善しますか? – Yuck

+0

実際、ナーバーは常に100%です。それは本質的に "高価な"ものではなく、 "そこに費やされた時間の大きさ"です。もしあなたがインデックスシークを減らすなら - あなたは100%どこか別のところに行くと思いますか?それは十分に速くなければならず、時間を費やす時間は意味をなさない必要があります。ここではインデックスを介したデータアクセスが行われます。しかし、数字は常に100として終わります - それは絶対的な重みではなく、相対的な重みです。 – TomTom

関連する問題