I have a stored proc that searches for products (250,000 rows) using a full text index.
The stored proc takes a parameter that is the full text search condition. This pa
OR
can crush performance, so do it this way:
DECLARE @Filter VARCHAR(100)
SET @Filter = 'FORMSOF(INFLECTIONAL, robe)'
IF @Filter IS NOT NULL
BEGIN
SELECT TOP 100 ID FROM dbo.Products
WHERE CONTAINS(Name, @Filter)
END
ELSE
BEGIN
SELECT TOP 100 ID FROM dbo.Products
END
Look at this article: Dynamic Search Conditions in T-SQL by Erland Sommarskog and this question: SQL Server 2008 - Conditional Query.
You've introduced an OR condition. In most cases it is simply much faster to check explicitly for NULL and perform one query vs your method.
For instance try this:
IF @Filter IS NULL
BEGIN
SELECT TOP 100 ID FROM dbo.Products
END
ELSE
BEGIN
SELECT TOP 100 ID FROM dbo.Products
WHERE @Filter CONTAINS(Name, @Filter)
END
The first query plan looks straightforward:
CONTAINS(Name, @Filter)
The concatenation operator forms a union of two recordsets. So it looks like the second query is doing:
@Filter
. If correct, the constant scan resolves @Filter is not null
.CONTAINS(Name, @Filter)
A hash join trades memory for speed; if your system has enough memory, it's much faster than a loop join. This can easily explan a 10-100x slowdown.
One fix is to use two distinct queries:
if @Filter is null
SELECT TOP 100 ID FROM dbo.Products
else
SELECT TOP 100 ID FROM dbo.Products WHERE CONTAINS(Name, @Filter)