I am querying table to select last n records but preserving the order. For this, I am using the following query which I got from 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
i.e I am selecting the last n records while preserving the sort order. Below is the dummy scripts to create the above tables:
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
Above I have created the table, applied index on it and inserted some dummy data in it. I am executing this query to get the records:
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
Below is the execution plan after running the above query:

As you can see the index is following but for inner query and you can see in the index plan that 77% of the execution is taken by the Sort process. How can I avoid that? What index should I apply here to overcome this situation.
The left-most sort which is consuming 77% of the execution plan is only working on your
TOP 10records. You can verify this by removing the finalORDER BY:It should be mentioned that all operators in a plan must add up to 100%. If your cheapest operation (i.e. sorting only 10 records) is consuming most of the execution time, then I’d say you’re in good shape.