2

我正在提高一些 sql 查询脚本的性能。例如:

SELECT * 
FROM Book b, Library l, [Order] o 
WHERE o.bookid = b.bookID 
AND o.mode = 'A' 
AND o.library_ID = l.library_ID 
AND l.library_ID > 19 
AND b.publisher_id  > 1000 
AND b.print_id > 800 
AND NOT EXISTS (
  SELECT * 
  FROM ExtBOOK 
  WHERE b.bookid = extbookid 
  AND library_ID = l.library_ID
) 
AND o.activated = 'Y' 
AND b.eisbn13 LIKE '978%' 
AND len(o.ext_user_id) > 3 
AND b.bookid > 200000 
AND b.bookid in (
  SELECT bookid 
  FROM category 
  WHERE categoryid  > 2
) 
ORDER BY o.orderid DESC

当我在 SQL Management Studio 中使用“包含实际执行计划”搜索此 sql 脚本时,结果要求我添加以下索引

CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>]
ON [dbo].[Order] ([MODE],[ACTIVATED],[LIBRARY_ID],[BOOKID])
INCLUDE ([OrderID],[EXT_USER_ID],[APPROVAL_DATE])

但是,如果我删除一些 where 条件,如下所示:

SELECT * FROM Book b, Library l, [Order] o 
WHERE o.bookid = b.bookID 
AND o.mode = 'A' 
AND o.library_ID = l.library_ID 
AND l.library_ID > 19 
ORDER BY o.orderid DESC

我得到了另一个不同的建议,如下所示:

CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>]
ON [dbo].[ORDER] ([MODE])
INCLUDE ([LIBRARY_ID],[BOOKID])

因为条件是可变的,我应该创建哪个索引?我了解索引的作用,但不了解被索引的字段和被包含的字段之间的好处。为什么在第一个推荐索引中,BOOKID 和 LIBRARY_ID 在索引字段中,而在第二个推荐索引中,BOOKID 和 LIBRARY_ID 在包含字段中?有什么区别,我应该使用哪个来涵盖所有可能的情况?

另外,从我的测试来看,我分别添加了它们来测试性能,但看不出有什么区别。我很感激任何帮助。

4

1 回答 1

1

您的索引策略在一定程度上取决于数据的预期波动性——如果您的数据稳定且很少更新,那么您可以添加更多索引来提高查询性能。但是,如果您的数据是易变的,并且经常更改,那么更多的索引将导致性能下降,因为索引会在数据更改时重新生成。

它还取决于您的查询的可预测性 - 它们是可预测的,在这种情况下将它们封装在存储过程或参数化查询中,还是它们完全是临时的?

我假设您已经在Order.BookIDand上有索引Order.Library_ID

此外,我会改写查询以使用内部连接语法 - 即:

SELECT * 
FROM [Order] o 
     INNER JOIN Library l
          ON o.library_ID = l.library_ID  
     INNER JOIN Book b  
          ON o.bookid = b.bookID 
WHERE 
     o.mode = 'A'  
AND 
     l.library_ID > 19 
于 2012-06-20T12:31:44.473 回答