我正在改进一些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])
如果我删除某些条件,如下所示:
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在包含的字段中?有什么区别,我应该用它来涵盖所有可能的条件?
另外,从我的测试中,我添加了每个测试性能,但看不出任何差异。我感谢任何帮助。
答案 0 :(得分:1)
您的索引策略在某种程度上取决于数据的预期波动性 - 如果您的数据很稳定且很少更新,那么您可以添加更多索引以帮助查询性能。但是,如果您的数据是易失性的,并且频繁更改,那么随着数据更改时重新生成索引,更多索引将导致性能降低。
它还取决于您的查询的可预测性 - 它们是否可预测,在这种情况下将它们封装在存储过程或参数化查询中,还是完全是临时的?
我假设您已经在Order.BookID
和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