索引字段和包含字段的索引之间的sql差异

索引字段和包含字段的索引之间的sql差异,sql,performance,tsql,indexing,non-clustered-index,Sql,Performance,Tsql,Indexing,Non Clustered Index,我正在改进一些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 ( SELE

我正在改进一些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])
创建非聚集索引[]
在[dbo].[ORDER]([MODE])
包括([LIBRARY\u ID],[BOOKID])
因为条件是可变的,我应该创建哪个索引?我了解索引的作用,但不了解索引字段和包含字段之间的好处。为什么在第一个推荐索引中,BOOKID和LIBRARY_ID在索引字段中,而在第二个推荐索引中,BOOKID和LIBRARY_ID在包含字段中?区别是什么?我应该用什么来涵盖所有可能的情况


此外,在我的测试中,我添加了每一个来测试性能,但没有看到任何差异。非常感谢您的帮助。

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

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

我假设您已经在
Order.BookID
Order.Library\u 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 

索引列是实际索引导航结构的一部分,例如,您可以在
WHERE
子句中使用它们。包含的列仅存在于索引的叶级中-您不能使用它们来选择行-它们存在于其中以便满足您的查询(查询请求的所有列)仅从索引结构开始,这样就不必对实际的表数据进行昂贵的键查找,就可以获得所需的一列或两列。@danmiao:别名“m”指的是哪个表(m.libary\u ID=l.library\u ID)?这是打字错误还是查询中有其他表格?嗨,8kb,很抱歉这是我的打字错误,是“o”,我已经更新了,谢谢你,非常感谢,我理解你的意思,只是一个类似的问题,我可以使用包含的列来按排序,或者我必须使用索引列来按排序,或
order by
不需要索引。如果要在
WHERE
order by
子句中使用列,则它必须是实际索引的一部分并存储在索引导航结构中。如果您有一个列作为“included”列,那么索引不能用于
orderby
Hi-podiluska,事实上,我在
ORDER.BookID
ORDER.Library\u ID
上有索引,但是,我看到您只是将隐式内部联接更改为显式内部联接,它们之间在查询性能上有差异。通常情况下,但我认为这会使意图更加清晰,这可能会提高可维护性