繁体   English   中英

在IF,OR上表现不佳

[英]Poor Performance on IF, 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 = @authorId OR @author = 0

因此,当输入参数@author > 0时,它返回特定作者的记录,如果为0则返回每个作者的记录。

即使我为@author传递任何大于0的值,性能都低于标准(尽管它并不是非常慢)。 然后我注意到如果我删除OR子句,存储过程运行得更快(对于相同的输入参数,至少快80%)。 然后我尝试做类似的事情:

IF @author > 0 
  --select records on a specific author
ELSE
  --select everything

但是,性能与OR非常相似。 无论如何以不同的方式编写类似的东西以获得更好的性能?

正如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)

但总是试着在执行计划中查看您的查询并比较结果

更新

如果需要条件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)

您应该向表中添加索引,包括where子句中的任何列。 这应该在authors表ID列上添加一个索引。

CREATE INDEX 'INDEX NAME'
    ON dbo.Author (ID); 

CREATE INDEX(Transact-SQL)

使用以下查询,我相信你会得到你的表现

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))

尝试这个
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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM