简体   繁体   English

在IF,OR上表现不佳

[英]Poor Performance on IF, OR

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. 因此,当输入参数@author > 0时,它返回特定作者的记录,如果为0则返回每个作者的记录。

Even when I pass any values greater than 0 for @author, the performance is sub-par (though it's not terribly slow). 即使我为@author传递任何大于0的值,性能都低于标准(尽管它并不是非常慢)。 I then notice if I remove the OR clause the stored procedure runs much faster (at least 80% faster for the same input parameter). 然后我注意到如果我删除OR子句,存储过程运行得更快(对于相同的输入参数,至少快80%)。 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. 但是,性能与OR非常相似。 Is there anyway to code something like this in a different way to gain better performance? 无论如何以不同的方式编写类似的东西以获得更好的性能?

As Nate S said, you need an index 正如Nate S所说,你需要一个索引

But in my experience, I got better performance using IN rather than OR 但根据我的经验,我使用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)

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. 如果需要条件WHERE子句,可以尝试使用这些替代方法。

Using CASE statement 使用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

Also if you set the @authorId = NULL rather than 0, you can use ISNULL function but better not to use functions in WHERE clause 另外如果你设置@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)

You should add an index to the table, including any columns in the where clause. 您应该向表中添加索引,包括where子句中的任何列。 This should add an index on the authors table ID column. 这应该在authors表ID列上添加一个索引。

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

CREATE INDEX (Transact-SQL) CREATE INDEX(Transact-SQL)

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

Try this 尝试这个
Joins hate OR 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