INCLUDE
在非聚集索引中有什么作用?
CREATE NONCLUSTERED INDEX [MyIndex] ON [dbo].[Individual]
(
[IndivID] ASC
)
INCLUDE ( [LastName], [FirstName])
WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
我知道第一部分用于WHERE
子句,但是INCLUDE
列做什么呢?将它们“添加到非聚集索引的叶级”有什么好处呢?
- edit* 另外,如果
IndivID
已有聚集PK索引,优化顾问为什么建议使用此索引?
4条答案
按热度按时间qyzbxkaa1#
INCLUDE列包含与索引关联的字段。它们不用于索引,但被放置在组成索引的B树的叶节点中。
本质上:索引仍然是ON [IndivID]和[IndivID]。但是,如果您的查询只需要[IndivID]、[LastName]和[FirstName]的子集,SQL在索引中找到要搜索的[IndivID]后,不需要返回表。
SEE:覆盖指数
编辑:B-tree假设MS SQL Server,我不确定其他实现是否使用相同的数据结构
优化顾问(推测)::聚集索引将整个数据行放置在索引的B树的叶节点上,这会占用大量空间。如果优化顾问发现您访问的字段不超过这三个([IndivID] + INCLUDEs),它将尝试将其降级为只显示“重要”字段的非聚集索引,以保存空间(以及插入/更新时间)。
wz1wpwve2#
INCLUDE
将这些字段添加到索引的叶子层,基本上bt-ree不按这些字段排序,但是一旦索引找到了包含它要查找的索引字段的行,它也会立即包含其他字段。如果你用电话簿来类比,电话簿索引中的
INCLUDED
字段(按Lastname
、Firstname
排序)将是Phone Number
和Address
--你不能通过这些字段查找一个人,但一旦你有了他们的名字,你就可以找到他们。CLUSTERED
索引在设计上已经包含了所有字段,因此INCLUDE
在CLUSTER
中是无效的。您也不应该为非聚集索引中的聚集字段设置INCLUDE
,因为它已经隐式地作为行键存在。我最经常使用
INCLUDE
字段进行聚合,例如,如果我有一个CalendarDate
和CustomerID
的索引,我可以包含PaidAmt
并得到MAX(PAidAmt) Where CustomerId = x AND CalendarDate = 1/1/2011
在最基本的级别上,它们用于避免书签或键查找。
juud5qan3#
这是作为有效负载包含在索引中的数据,它不会被用于过滤,但可以被返回。
例如,如果您有一个按年龄和返回名称筛选的查询:
然后可以为
age
字段创建一个索引,其中包含name
字段,这样数据库就可以只使用索引来运行整个查询,而不必从实际表中读取任何内容。pbpqsu0x4#
来自MSDN -CREATE INDEX (Transact-SQL):
包括(第[,... n ]栏)
指定要添加到非聚集索引的叶级的非键列。
也就是说,您可以向非聚集索引中添加更多列-如果每次查询键列时都返回多个字段,则将它们添加到索引中将提高性能,因为它们与索引一起存储,也称为覆盖索引。