views:

252

answers:

3

Is it a good idea to index varchar columns only used in LIKE opertations? From what I can read from query analytics I get from the following query:

SELECT * FROM ClientUsers WHERE Email LIKE '%niels@bosmainter%'

I get an "Estimated subtree cost" of 0.38 without any index and 0.14 with an index. Is this a good metric to use for anlayzing if a query has been optimized with an index?

+7  A: 

In my experience the first %-sign will make any index useless, but one at the end will use the index.

idstam
Close enough - LIKE will use the prefix on an index but you can't resolve a wildcard through an index so that's as far as it will go.
ConcernedOfTunbridgeWells
So yay or nay for indexes on these columns?
Niels Bosma
If you always query the column with a leading %, the index will never be used. The answer thus depends on how you query your data.
Lieven
*NOT COMPLETELY TRUE* see my answer, you can hit an index on _LIKE "%abc"_ queries with a little extra work
KM
**NOT COMPLETELY TRUE**, you _CAN_ hit an index on queries that use _LIKE '%xyz'_, but you need to do a little extra work, see my answer for an explanation
KM
+1  A: 

To answer the metrics part of your question: The type of index/table scan/seek being performed is a good indicator for knowing if an index is being (properly) used. It's usually shown topmost in the query plan analyzer. The following scan/seek types are sorted from worst (top) to best (bottom):

  • Table Scan
  • Clustered Index Scan
  • Index Scan
  • Clustered Index Seek
  • Index Seek

As a rule of thumb, you would normally try to get seeks over scans whenever possible. As always, there are exceptions depending on table size, queried columns, etc. I recommend doing a search on StackOverflow for "scan seek index", and you'll get a lot of good information about this subject.

MicSim
+6  A: 

Given the data 'abcdefg'

WHERE Column1 LIKE '%cde%'  --can't use an index

WHERE Column1 LIKE 'abc%' --can use and index

WHERE Column1 Like '%defg' --can't use an index, but see note below

Note: If you have important queries that require '%defg', you could use a persistent computed column where you REVERSE() the column and then index it. Your can then query on:

WHERE Column1Reverse Like REVERSE('defg')+'%' --can use the persistent computed column's index
KM
I like your solution, though I'd call it an ugly hack ;)
idstam
I've used this ugly hack on a system where the original designer made numbers char(x) with leading zeros and other keys letter+ leading zeros. try telling users they have to enter in the leading zeros and or letter+ leading zeros! ha. they want to enter in 203, not G000000203, so this reverse() "hack" will help there.
KM