[英]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);
使用以下查詢,我相信你會得到你的表現
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.