I have a table [MyTable] with a column [MyColumn] NVarchar(50). I have a nonclustered index on this column, now while running the below two queries:
SELECT 1
FROM [MyTable] M
WHERE M.[MyColumn] = @MyColumn
SELECT 1
FROM [MyTable] M
WHERE M.[MyColumn] = COALESCE(@MyColumn, M.[MyColumn] )
I noticed the first query is using Index Seek (NonClustered) and the second one is using Index Scan (Non Clustered). May I know how will I make use of index seek with coalesce or isnull ?
For your specific case I would say isnull is clearly faster. This is not to say it is better in any other given situation. Using straight up values, or nvarchars or bits instead of int, or a column that is not a primary key, or Nesting isnull versus adding parameters to coalesce could change things.
COALESCE() is literally shorthand for a CASE statement, they will perform identically. However, as podiluska mentioned, ISNULL() can be occasionally faster than a CASE statement, but it's likely to be a miniscule increase as these functions are very unlikely to bottleneck your procedure.
A COALESCE function returns the first non-NULL expression from a specified list. Usually, we use COALESCE as one of the elements in the select list, however, it can be successfully used in the join conditions too.
You can use coalesce anywhere, including the where clause, yes.
May I know how will I make use of index seek with coalesce or isnull ?
Perhaps not an answer to your question but you can have two different queries. One for the case where @MyColumn is null
and one for the case where you want to use @MyColumn
in the where clause.
IF @MyColumn IS NULL
BEGIN
SELECT 1
FROM [MyTable] M
END
ELSE
BEGIN
SELECT 1
FROM [MyTable] M
WHERE M.[MyColumn] = @MyColumn
END
This isn't easy, since as Alex pointed out using the functions forces a scan, since the optimizer knows it needs to check every row.
What you CAN do is created a Computed Column for the result of your function, and index that column.
There's not really a prettier way to get a seek.
EDIT:
In rereading your question, this may not be an option for you unless you rethink your logic. You are integrating a variable into the function, and there is absolutely no way to index that.
EDIT 2:
Instead of your current logic, try something like:
...
WHERE (M.[MyColumn] = @MyColumn
OR @MyColumn IS NULL)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With