索引这块从存储结构来分,有2大类,聚集索引和非聚集索引,而非聚集索引在堆表或者在聚集索引表都会对其 键值有所影响,这块可以详细查看本系列第二篇文章:SQL SERVER大话存储结构_(2)_非聚集索引如何查找到行记录
 
    非聚集索引内又分为多类:单列索引、复合索引、包含索引、过滤索引等。之前文章有具体分析过非聚集索引的存储情况,但是没有对复合索引及包含索引做过多说明,本文来讲讲这两个索引。
   SQL SERVER大话存储结构(4)_复合索引与包含索引


    如果转载,请注明博文来源: www.cnblogs.com/xinysu/   ,版权归 博客园 苏家小萝卜 所有。望各位支持!
 
    本系列上一篇博文链接:SQL SERVER大话存储结构(3)_数据行的行结构


--复合索引
CREATE INDEX IndexName ON tbname(columna,columnb [,columnc...] )
 
--包含索引
CREATE INDEX IndexName ON tbname(columna [,columnb,columnc...] ) INCLUDE (column1 [,column2,column3...])
     复合索引,顾名思义,及多个列组成的索引,列的顺序非常重要,关系到查询性能,这点后面会说明。
     包含索引,建索引SQL 中含有 include 字段,索引键值用于WHERE条件过滤,INCLUDE字段用于 SELECT 展示,这点后面也会说明。
     无论是符合索引还是包含索引,都有索引键值长度不能超过900字节的限制,但是要注意一点,包含索引的include字段是不包括在里边的。

2 索引页存储情况

    从索引页的存储情况来分析,分析过程中,重点在查看复合索引跟包含包含索引在 子节点及叶子结点的键值情况。

2.1 创建测试表格

    创建表格 tbindex,建立两个测试索引,同时造数据。
 1 CREATE TABLE tbindex(
 2 id int identity(1,1) not null primary key ,
 3 name varchar(50) not null,
 4 type varchar(10) not null,
 5 numbers int not null
 6 )
 7 GO
 8  
 9 CREATE INDEX ix_number_name ON tbindex(numbers,name)
10 GO
11 CREATE INDEX ix_name ON tbindex(numbers) INCLUDE (name)
12 GO
13  
14 DECLARE @ID INT
15 SET @ID=1
16 WHILE @ID<=5
17 BEGIN
18      INSERT INTO tbindex(name,type,numbers)
19      SELECT
20            name,
21          type,
22          object_id+@id
23      FROM sys.objects
24  
25         SET @ID=@ID+1
26 END

2.2 分析索引行

--查看该表格索引的id情况
SELECT * FROM sys.indexes WHERE object_id=object_id('tbindex')
--PK__tbindex__3213E83F89582AC3    1
--ix_number_name    2
--ix_number    3
 
DBCC traceon(3604)
DBCC ind('dbpage','tbindex',-1)
 
DBCC PAGE('dbpage',1,395,3)
DBCC PAGE('dbpage',1,396,3)
 
DBCC PAGE('dbpage',1,397,3)
DBCC PAGE('dbpage',1,398,3)
 SQL SERVER大话存储结构(4)_复合索引与包含索引

SQL SERVER大话存储结构(4)_复合索引与包含索引

SQL SERVER大话存储结构(4)_复合索引与包含索引

SQL SERVER大话存储结构(4)_复合索引与包含索引
    分析查看,得知:
  • 复合索引 IX_number_name的索引节点为pageid=395,再挑选一个叶子结点来分析 pageid=396;
  • 包含索引 IX_number 的索引节点为 pageid=397,再挑选一个叶子节点来分析 pageid=398。
 
--复合索引,395为索引页节点,396为索引页叶子节点
DBCC PAGE('dbpage',1,395,3)
DBCC PAGE('dbpage',1,396,3)
 
--包含索引,397为索引页节点,398为索引页叶子节点
DBCC PAGE('dbpage',1,397,3)
DBCC PAGE('dbpage',1,398,3)
 
 SQL SERVER大话存储结构(4)_复合索引与包含索引

 

    从这里可以看出,复合索引跟包含索引的 所有索引列都会存储在索引叶子节点跟子节点,但是包含索引 的INCLUDE列,不在索引页的子节点存储,仅存储在 索引页的叶子节点上。
    从这里不难理解,为什么之前说 include列用于 select 列,而不用于 where 列过滤。因为非聚集索引当索引页面有多层的时候,是先查询 索引的子节点,再查询索引的叶子节点,而包含索引的INCLUDE列不在叶子节点中存储,无法根据其来进行过滤。

3  对查询的影响

3.1 复合索引查询注意事项

     由于需要数据量作为实验支持,所以不用之前分析索引行结构的表格tbindex,换个高大上 tb_composite 如下。
 
 1 create table tb_composite(
 2 id int identity(1,1) not null primary key,
 3 name varchar(50) not null,
 4 userid int not null,
 5 timepoint datetime not null
 6 )
 7 GO
 8  
 9 create index ix_userid_name on tb_composite(userid,name)
10 GO
11  
12 create index ix_userid on tb_composite(userid)
13 GO
14  
15 INSERT INTO tb_composite(name,userid,timepoint)
16 SELECT
17       newid(),orderid%10000 ,CreatedDate
18 FROM ORDERS
大数据表格

相关文章:

  • 2021-06-16
  • 2021-08-17
  • 2022-12-23
  • 2021-05-02
  • 2022-01-21
  • 2022-01-07
猜你喜欢
  • 2021-09-30
  • 2021-09-29
  • 2022-02-24
  • 2022-12-23
  • 2022-12-23
  • 2022-02-11
  • 2022-01-21
相关资源
相似解决方案