我有类似这样的存储过程:
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
因此,当输入参数@author
为> 0它返回特定作者的记录,如果为0则返回每个作者的记录。
即使我为@author传递任何大于0的值,性能也低于标准(尽管它并不是非常慢)。然后我注意到如果我删除OR子句,存储过程运行得更快(对于相同的输入参数,至少快80%)。然后我尝试做类似的事情:
IF @author > 0
--select records on a specific author
ELSE
--select everything
但是,性能与OR非常相似。无论如何以不同的方式编写类似的东西以获得更好的性能?
答案 0 :(得分:2)
正如Nate S所说,你需要一个索引
但根据我的经验,我使用IN
而不是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)
但总是尝试在execution plan中查看您的查询并比较结果
<强>更新强>
如果你想要条件WHERE
子句,你可以试试这些替代方案。
使用CASE
声明
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
此外,如果您设置@authorId = NULL
而不是0,则可以使用ISNULL
函数,但最好不要使用WHERE
子句中的函数
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)
答案 1 :(得分:1)
您应该向表中添加索引,包括where子句中的任何列。这应该在authors表ID列上添加一个索引。
CREATE INDEX 'INDEX NAME'
ON dbo.Author (ID);
答案 2 :(得分:0)
使用以下查询,我相信你会得到你的表现
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))
答案 3 :(得分:0)
试试这个
Joins
讨厌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