Saturday 2 April 2011

Control Locking with SQL Full Text Search and CONTAINSTABLE

One of our systems at work uses SQL Full Text Search to let users search for products using text descriptions. However, users often complain of slow performance or even time-outs.

After some investigation, I concluded that, besides performance issues, there were also some process blocking due to SQL locks. So I not only restructured these queries and added indexes to make them more efficient, I also added "WITH (NOLOCK)" to some of the queries (where dirty reads is not an issue).

My further testing showed that locks on a table will also block Full Text Searches using CONTAINSTABLE(). However, you cannot add "WITH (NOLOCK)" when you are selecting from CONTAINSTABLE(). So, is it possible to ignore locks when using CONTAINSTABLE()?

Well, as it turns out, you can. I remembered that "WITH (NOLOCK)" is equivalent to setting the transaction isolation level to READ UNCOMMITTED. So I just set it before the CONTAINSTABLE() statement and reset it afterward, like so:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT
    KEY, RANK
FROM CONTAINSTABLE(Product, Description, @SearchTerm);
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

Testing confirmed that this allows the use of CONTAINSTABLE() while ignoring table locks. And as they say, voilĂ , problem solved.

1 comment:

Unknown said...

Thanks, this helped me out.