SQL Server 'INCLUDE'在索引中有什么作用?

chy5wohz  于 2022-12-26  发布在  其他
关注(0)|答案(4)|浏览(192)

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索引,优化顾问为什么建议使用此索引?
qyzbxkaa

qyzbxkaa1#

INCLUDE列包含与索引关联的字段。它们不用于索引,但被放置在组成索引的B树的叶节点中。
本质上:索引仍然是ON [IndivID]和[IndivID]。但是,如果您的查询只需要[IndivID]、[LastName]和[FirstName]的子集,SQL在索引中找到要搜索的[IndivID]后,不需要返回表。
SEE:覆盖指数
编辑:B-tree假设MS SQL Server,我不确定其他实现是否使用相同的数据结构
优化顾问(推测)::聚集索引将整个数据行放置在索引的B树的叶节点上,这会占用大量空间。如果优化顾问发现您访问的字段不超过这三个([IndivID] + INCLUDEs),它将尝试将其降级为只显示“重要”字段的非聚集索引,以保存空间(以及插入/更新时间)。

wz1wpwve

wz1wpwve2#

INCLUDE将这些字段添加到索引的叶子层,基本上bt-ree不按这些字段排序,但是一旦索引找到了包含它要查找的索引字段的行,它也会立即包含其他字段。
如果你用电话簿来类比,电话簿索引中的INCLUDED字段(按LastnameFirstname排序)将是Phone NumberAddress--你不能通过这些字段查找一个人,但一旦你有了他们的名字,你就可以找到他们。
CLUSTERED索引在设计上已经包含了所有字段,因此INCLUDECLUSTER中是无效的。您也不应该为非聚集索引中的聚集字段设置INCLUDE,因为它已经隐式地作为行键存在。
我最经常使用INCLUDE字段进行聚合,例如,如果我有一个CalendarDateCustomerID的索引,我可以包含PaidAmt并得到
MAX(PAidAmt) Where CustomerId = x AND CalendarDate = 1/1/2011
在最基本的级别上,它们用于避免书签或键查找。

juud5qan

juud5qan3#

这是作为有效负载包含在索引中的数据,它不会被用于过滤,但可以被返回。
例如,如果您有一个按年龄和返回名称筛选的查询:

select name
from persons
where age = 42

然后可以为age字段创建一个索引,其中包含name字段,这样数据库就可以只使用索引来运行整个查询,而不必从实际表中读取任何内容。

pbpqsu0x

pbpqsu0x4#

来自MSDN -CREATE INDEX (Transact-SQL)
包括(第[,... n ]栏)
指定要添加到非聚集索引的叶级的非键列。
也就是说,您可以向非聚集索引中添加更多列-如果每次查询键列时都返回多个字段,则将它们添加到索引中将提高性能,因为它们与索引一起存储,也称为覆盖索引。

相关问题