6

I using next queries for extracting top 100 and 101 lines from DB and gettings following elapsing times, which completely different (second query ~8 slower than first):

SELECT TOP (100) *
 FROM PhotoLike WHERE photoAccountId=@accountId AND accountId<>@accountId
 ORDER BY createDate DESC
GO

SQL Server Execution Times: CPU time = 187 ms, elapsed time = 202 ms.

SELECT TOP (101) *
 FROM PhotoLike WHERE photoAccountId=@accountId AND accountId<>@accountId
 ORDER BY createDate DESC
GO

SQL Server Execution Times: CPU time = 266 ms, elapsed time = 1644 ms.

Execution plan of first two cases: Select top 100 and 101 with variable

But if I get rid of @accoundId variable, I get following results, which approximately equals and faster more than 2 times than first query from this question.

SELECT TOP (100) *
 FROM PhotoLike WHERE photoAccountId=10 AND accountId<>10
 ORDER BY createDate DESC
GO

SQL Server Execution Times: CPU time = 358 ms, elapsed time = 90 ms.

SELECT TOP (101) *
 FROM PhotoLike WHERE photoAccountId=10 AND accountId<>10
 ORDER BY createDate DESC
GO

SQL Server Execution Times: CPU time = 452 ms, elapsed time = 93 ms.

Execution plan of second two cases: Select top 100 and 101 without variable

Why is this happen and how can I improve performance with varibales?

UPDATE

Added execution plans.

7
  • 2
    Have you looked at the execution plan? Commented Aug 8, 2013 at 12:45
  • 3
    TOP 100/TOP 101 is known problem, see this blog. Speed degradation with parameters is probably due to parameter sniffing. Commented Aug 8, 2013 at 12:48
  • @NikolaMarkovinović - This is the opposite of parameter sniffing, Variables aren't sniffed except if using OPTION (RECOMPILE) so it just makes a generic guess not based on the actual values at all. The TOP 101 behaviour isn't always a problem though looks like it is in this case. It is the cut off point between doing a full sort and a TOP N sort. Commented Aug 8, 2013 at 12:59
  • @MarkSowul - Nope. In fact assigning to local variables is still a semi popular workaround to avoid parameter sniffing precisely because they aren't sniffed. Commented Aug 8, 2013 at 13:04
  • @MartinSmith Thanks for the info. I assumed OP is using stored procedure - that would explain timings. As for TOP 100 i never liked solution given in this blog, and after browsing through your link I know why :-) Commented Aug 8, 2013 at 13:06

3 Answers 3

2

There are a couple of things going on here.

When you use variables SQL Server doesn't sniff the values at all except if you also add OPTION (RECOMPILE).

The estimate for the number of rows matching photoAccountId=@accountId is much smaller with the guess than is actually the case. (Note the thick line coming out of the index seek in the second plan and the decision to use a parallel plan).

Also TOP 100 / TOP 101 is the cut off point between the TOP N sort using an algorithm that just needs space to sort 100 rows and it doing a full sort.. The inaccurate row count estimate likely means there is insufficient memory allocated for the full sort and it is spilling to tempdb.

Simply adding OPTION (RECOMPILE) to the query with variables will likely improve things somewhat though it looks as though even the "fast" plan is doing many key lookups that could be avoided with different indexing.

Sign up to request clarification or add additional context in comments.

Comments

0

I wonder if this could be parameter sniffing related. How fast does the following query go?

DECLARE @accountIdParam int;
SELECT @accountIdParam = @accountId;

SELECT TOP (101) *
FROM PhotoLike WHERE photoAccountId=@accountIdParam AND accountId<>@accountIdParam
ORDER BY createDate DESC
GO

1 Comment

@KvanTTT Well, what I gave is a work-around for parameter sniffing, so it doesn't seem like that's the problem.
0

I you can, you should create a clustered index based on the accountId field of your table.

As you test a inequality, it should be more performant :

CREATE UNIQUE CLUSTERED INDEX [IX_MyIndexName] ON [dbo].[PhotoLike] ( accountId DESC, createDate DESC, photoAccountId DESC, )

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.