1

最後の n レコードを選択するためにテーブルをクエリしていますが、順序は保持しています。このために、Select Top N Records Ordered by X, But Have Results in Reverse Orderから取得した次のクエリを使用しています。

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

以下は、上記のクエリを実行した後の実行計画です。

ここに画像の説明を入力

ご覧のとおり、インデックスは次のとおりですが、内部クエリの場合とインデックス プランで、実行の 77% がソート プロセスによって行われていることがわかります。どうすればそれを回避できますか? この状況を克服するには、ここでどの指標を適用すればよいでしょうか。

4

1 に答える 1

5

実行計画の 77% を消費している一番左の並べ替えは、TOP 10レコードに対してのみ機能しています。final を削除することでこれを確認できます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 レコードのみの並べ替え) が実行時間のほとんどを消費している場合は、良好な状態にあると言えます。

ここに画像の説明を入力

于 2012-04-13T12:19:05.543 に答える