关于从表中选择最后n条记录的表现

Roc*_*ngh 1 sql sql-server indexing sql-server-2005

我正在查询表以选择最后n条记录但保留顺序.为此,我使用以下查询,我从选择X排序的前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
Run Code Online (Sandbox Code Playgroud)

即我在保留排序顺序的同时选择最后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
Run Code Online (Sandbox Code Playgroud)

上面我创建了表,在其上应用了索引并在其中插入了一些虚拟数据.我正在执行此查询以获取记录:

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
Run Code Online (Sandbox Code Playgroud)

以下是运行上述查询后的执行计划:

在此输入图像描述

正如您所看到的那样,索引正在跟随,但对于内部查询,您可以在索引计划中看到,排序过程执行了77%的执行.我怎么能避免这种情况?我应该在这里应用什么指数来克服这种情况.

Yuc*_*uck 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
Run Code Online (Sandbox Code Playgroud)

应该提到的是,计划中的所有运营商必须加起来达到100%.如果你最便宜的操作(即只排序10条记录)占用大部分执行时间,那么我会说你的状态很好.

在此输入图像描述