THE SQL Server Blog Spot on the Web

Welcome to - The SQL Server blog spot on the web Sign in | |
in Search

Rob Farley

- Owner/Principal with LobsterPot Solutions (a MS Gold Partner consulting firm), Microsoft Certified Master, Microsoft MVP (SQL Server), APS/PDW trainer and leader of the SQL User Group in Adelaide, Australia. Rob is a former director of PASS, and provides consulting and training courses around the world in SQL Server and BI topics.

Turning a Scan into a Seek With A Pointless Predicate

Hi! - Great that you've found this page, but it's no longer here! You can find the content over at:

Published Wednesday, May 25, 2011 11:50 PM by Rob Farley

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS



AaronBertrand said:

Hey Rob, if you used Plan Explorer to analyze the plan, among other things, you wouldn't have to deal with truncated names. :-)

May 25, 2011 9:29 AM

Rob Farley said:

Plan Explorer still seems to cut that one off - although it does show a bit more. The tooltip shows the whole name in both SSMS and SSPE.

But yeah, I keep feeling tempted to use SSPE for these diagrams, if only because it has the rowcount shown clearly.

May 25, 2011 9:36 AM

AaronBertrand said:

Right-click the plan diagram and select "Full Object Names" :-)

May 26, 2011 9:54 AM

Kalen Delaney said:

Hi Rob

I just found this post today...

I have a really simple demo in my 5-day internals class where I show a plan that says it's doing a seek, but it actually looking at every single row in the table. So I stress to my students that just because the plan says 'seek', doesn't always means it's a great (or fast) plan. You have to look at rowcounts and costs also.



August 13, 2013 10:04 AM

Rob Farley said:

Sounds good, Kalen. I find so many people fail to appreciate the residual Predicate's effect on a Seek operation, when the Seek Predicate is not selective enough. I feel like it turns up in almost every tuning exercise, and yet so many people miss it.

I love OPTION (QUERYTRACEON 9130) for giving a better indication about what's happening. :)


August 13, 2013 10:24 AM

Rob Farley said:

I have other posts that relate to this as well, such as the one called "Covering Schmuvvering", one on "Probe Residual when you have a Hash Match" (not actually about airport security).

August 13, 2013 10:29 AM

Kalen Delaney said:

I was just linking around to some of your related posts, and found that you have an example almost exactly like mine in this post:

select *

from Production.Product

where ProductID < 999999999;

I basically explain it like this: There are only 2 operations that can be used on indexes: seeks and scans. And a scan is only used when the optimizer is absolutely sure it will have to look at every single row. And if it can't be sure it's a scan, the plan will say seek. Even if it's a whole lot of rows ...

August 13, 2013 10:39 AM

Rob Farley said:

I point out that it's a Seek if there's a predicate being used as a Seek Predicate, which essentially the same sentiment. The Seek Predicate can be used to find the start of the RangeScan and then when to stop, while the Predicate is the "check" that is applied to every row in the Range. The Seek Predicate is applied to every row in the Range too, but the reaction of "predicate not satisfied" is to mark the end of the Range (thereby stopping the RangeScan).

August 13, 2013 5:50 PM

Sachin Dhir said:

Visit below link for more details on Scan Vs Seek

Scan indicates reading the whole of the index/table looking for matches – the time this takes is proportional to the size of the index.

Seek, on the other hand, indicates b-tree structure of the index to seek directly to matching records – time taken is only proportional to the number of matching records.

March 9, 2015 4:36 AM

Rob Farley said:

Hi Sachin,

I'm sorry, but you're somewhat wrong.

A Scan starts at the beginning of the index (or at the end of it's going backwards) to look for matches. It stops when it stops being asked for more records, or when it has looked through the index. A Seek starts at a particular position and then scans through a particular range. It also stops when it stops being asked for more records, or if the range it is looking through is done.

While the range of a Seek might be smaller than the whole index, it might not be.

Also - in your post you say that a Clustered Index Scan is better than an Index Scan. That's almost never true. You also say that a Table Scan is the worst, but that is also very contentious.

Your post talks about the number of rows that satisfy the Predicate. You actually mean the Seek Predicate. As I showed in this post, if the Seek Predicate satisfies just about every row, then the Seek becomes worse than the Scan, which is hidden by the selectivity of the Predicate.

I feel like your comment is just trying to lure people to your website - and I will remove the link soon as I don't consider your website is helpful, and is even wrong in some situations.


March 9, 2015 5:02 AM

Leave a Comment


This Blog



No tags have been created or used yet.


News? Haven't you read my blog?

My Company

Can't find something?

Contact Me

Twitter: @rob_farley
Skype: rob_farley

MVP (SQL Server)


Adelaide SQL UG

Privacy Statement