Reputation: 1231
I have a stored procedure similar to something like this:
SELECT a.Name AS Author,
b.Price,
b.PublishDate,
b.Title,
b.ISBN
FROM Book b
INNER JOIN Author a ON b.Id = a.BookId
WHERE a.Id = @authorId OR @author = 0
So when the input parameter @author
is > 0 it returns records on a specific author, if 0 it returns records on every author.
Even when I pass any values greater than 0 for @author, the performance is sub-par (though it's not terribly slow). I then notice if I remove the OR clause the stored procedure runs much faster (at least 80% faster for the same input parameter). I then try to do something like:
IF @author > 0
--select records on a specific author
ELSE
--select everything
However, the performance is pretty the same as OR. Is there anyway to code something like this in a different way to gain better performance?
Upvotes: 1
Views: 80
Reputation: 45096
Try this
Joins
hate OR
SELECT a.Name AS Author,
b.Price,
b.PublishDate,
b.Title,
b.ISBN
FROM Book b
INNER JOIN Author a ON b.Id = a.BookId and a.Id = @authorId
union
SELECT a.Name AS Author,
b.Price,
b.PublishDate,
b.Title,
b.ISBN
FROM Book b
INNER JOIN Author a ON b.Id = a.BookId and @author = 0
Upvotes: 0
Reputation: 1057
Use below query and i am sure you will get your performance
SELECT a.Name AS Author,
b.Price,
b.PublishDate,
b.Title,
b.ISBN
FROM Book b
INNER JOIN Author a ON b.Id = a.BookId
WHERE a.Id IN (@authorId, 0)
option(OPTIMIZE for(@authorId =10))
Upvotes: 0
Reputation: 5672
As Nate S said, you need an index
But in my experience, I got better performance using IN
rather than OR
SELECT a.Name AS Author,
b.Price,
b.PublishDate,
b.Title,
b.ISBN
FROM Book b
INNER JOIN Author a ON b.Id = a.BookId
WHERE a.Id IN (@authorId, 0)
But always try to see your query in execution plan and compare the result
Update
If you want conditional WHERE
clause, you can use try these alternatives.
Using CASE
statement
SELECT a.Name AS Author,
b.Price,
b.PublishDate,
b.Title,
b.ISBN
FROM Book b
INNER JOIN Author a ON b.Id = a.BookId
WHERE a.Id = CASE @authorId WHEN 0 THEN a.Id ELSE @authorId END
Also if you set the @authorId = NULL
rather than 0, you can use ISNULL
function but better not to use functions in WHERE
clause
SELECT a.Name AS Author,
b.Price,
b.PublishDate,
b.Title,
b.ISBN
FROM Book b
INNER JOIN Author a ON b.Id = a.BookId
WHERE a.Id ISNULL(@authorId, a.Id)
Upvotes: 2
Reputation: 1157
You should add an index to the table, including any columns in the where clause. This should add an index on the authors table ID column.
CREATE INDEX 'INDEX NAME'
ON dbo.Author (ID);
Upvotes: 1