views:

1707

answers:

5

By definition (at least from what I've seen) sargable means that a query is capable of having the query engine optimize the execution plan that the query uses. I've tried looking up the answers, but there doesn't seem to be a lot on the subject matter. So the question is, what does or doesn't make an SQL query sargable? Any documentation would be greatly appreciated.

For reference: Sargable

A: 

According to Wikipedia (I'd never heard this term before), what it means is that the engine is able to make use of the indexes in your database in order to optimize the query. As to what specifically makes an index a candidate for use in a particular query, I'll leave that up to the mountains of information on the web relating to query and index optimization.

Adam Robinson
defining sargable from wikipedia and referencing a google query, hardly answers the question
Greg Dean
@Greg: Yes, yours was far more helpful :) This isn't a question that CAN be answered. The sort of information that goes into optimizing a query toward particular indexes (or, conversely, creating an index tuned for a particular query or set of them) is far beyond the scope of a simple question-and-answer website like SO. A google search for information particular to your own RDBMS and situation will be more helpful.
Adam Robinson
@Adam, I didn't answer the question w/ vapor because I don't know the answer. So, I'm not sure what you are talking about. We are all aware of google and wikipedia, your answer is just not helpful.
Greg Dean
@Greg: Sarcasm. An answer that points to a source of information is more helpful than one that doesn't exist. Of course everyone knows about the resources. Being told that it's likely your only source of anything close to a comprehensive solution (or the start of one) is not immediately obvious. Hence the answer.
Adam Robinson
Adam's answer was helpful to me. I had forgotten/never heard of the term before.
p.campbell
@Adam: You answered within 4 minutes of the question being created. I don't think there was a risk (yet) of the question going unanswered, by someone that actually has relevant opinion/answer, but thanks for the link to google. You are right, it was very helpful.
Greg Dean
The definition of Sargable belongs as part of the question. Not an answer
Greg Dean
@Greg: Thanks, glad you found it useful! It's always good to hear from a fan.
Adam Robinson
I like Adam's answer because it's a point into the right direction instead of a regurgitation of what i found during my initial research. I missed the part about it making full use of indexes and didn't clue into idex optimization.
DForck42
Greg Dean
+12  A: 

Don't do this:

WHERE Field LIKE '%blah%'

That causes a table/index scan.

Don't do this:

WHERE FUNCTION(Field) = 'BLAH'

That causes a table/index scan.

The database server will have to evaluate FUNCTION() against every row in the table and then compare it to 'BLAH'.

If possible, do it in reverse:

WHERE Field = INVERSE_FUNCTION('BLAH')

This will run INVERSE_FUNCTION() against the parameter once and will still allow use of the index.

beach
Your suggestion with flipping the function would really only work when the function round-trips data (meaning that f(f(n)) = n).
Adam Robinson
True. I considered adding INVERSE_FUNCTION but didn't want to be confusing. I'll change it.
beach
A: 

I might also add to Adam's answer, that the mountains of information are in most cases extremely particular to each DB engine.

hoagie
then just comment on his answer...
Greg Dean
He's not able to.
Chris
+22  A: 

The most common thing that will make a query non-sargable is to include a field inside a function in the where clause:

SELECT ... FROM ...
WHERE Year(myDate) = 2008

The SQL optimizer can't use an index on myDate, even if one exists. It will literally have to evaluate this function for every row of the table. Much better to use:

WHERE myDate >= '01-01-2008' AND myDate < '01-01-2009'

Some other examples:

Bad: Select ... WHERE isNull(FullName,'') = 'Ed Jones'
Fixed: Select ... WHERE ((FullName = 'Ed Jones') OR (FullName IS NULL))

Bad: Select ... WHERE SUBSTRING(DealerName,4) = 'Ford'
Fixed: Select ... WHERE DealerName Like 'Ford%'

Bad: Select ... WHERE DateDiff(mm,OrderDate,GetDate()) >= 30
Fixed: Select ... WHERE OrderDate < DateAdd(mm,-30,GetDate())
BradC
+1  A: 

In this answer I assume the database has sufficient covering indexes. There are enough questions about this topic.

A lot of the times the sargability of a query is determined by the tipping point of the related indexes. The tipping point defines the difference between seeking and scanning an index while joining one table or result set onto another. One seek is of course much faster than scanning a whole table, but when you have to seek a lot of rows, a scan could make more sense.

So among other things a SQL statement is more sargable when the optimizer expects the number of resulting rows of one table to be less than the tipping point of a possible index on the next table.

You can find a detailed post and example here.

Dries Van Hansewijck