Full text search vs LIKE

profvm picture profvm · Nov 16, 2010 · Viewed 19.8k times · Source

My question is about using fulltext.As I know like queries which begin with % never use index :

SELECT * from customer where name like %username%

If I use fulltext for this query can ı take better performance? Can SQL Server use fulltext index advantages for queries like %username%?

Answer

Mike Chamberlain picture Mike Chamberlain · Dec 1, 2010

Short answer

There is no efficient way to perform infix searches in SQL Server, neither using LIKE on an indexed column, or with a fulltext index.

Long answer

In the general case, there is no fulltext equivalent to the LIKE operator. While LIKE works on a string of characters and can perform arbitrary wildcard matches against anything inside the target, by design fulltext operates upon whole words/terms only. (This is a slight simplification but it will do for the purpose of this answer.)

SQL Server fulltext does support a subset of LIKE with the prefix term operator. From the docs (http://msdn.microsoft.com/en-us/library/ms187787.aspx):

SELECT Name
FROM Production.Product
WHERE CONTAINS(Name, ' "Chain*" ');

would return products named chainsaw, chainmail, etc. Functionally, this doesn't gain you anything over the standard LIKE operator (LIKE 'Chain%'), and as long as the column is indexed, using LIKE for a prefixed search should give acceptable performance.

The LIKE operator allows you to put the wildcard anywhere, for instance LIKE '%chain', and as you mentioned this prevents an index from being used. But with fulltext, the asterisk can only appear at the end of a query term, so this is of no help to you.

Using LIKE, it is possible to perform efficient postfix searches by creating a new column, setting its value to the reverse your target column, and indexing it. You can then query as follows:

SELECT Name
FROM Production.Product
WHERE Name_Reversed LIKE 'niahc%'; /* "chain" backwards */

which returns products with their names ending with "chain".

I suppose you could then combine the prefix and reversed postfix hack:

SELECT Name
FROM Production.Product
WHERE Name LIKE 'chain%'
AND Name_Reversed LIKE 'niahc%';

which implements a (potentially) indexed infix search, but it's not particularly pretty (and I've never tested this to see if the query optimizer would even use both indexes in its plan).