上篇主要说了聚集索引和简单介绍了一下非聚集索引,相信大家一定对聚集索引和非聚集索引开始有一点了解了。
这篇文章只是作为参考,里面的观点不一定正确
上篇的地址:SQLSERVER聚集索引与非聚集索引的再次研究(上)
下篇主要说非聚集索引
先上非聚集索引的结构图
先创建Department8表
1 --非聚集索引 2 USE [pratice] 3 GO 4 5 CREATE TABLE Department8( 6 DepartmentID int IDENTITY(1,1) NOT NULL , 7 Name NVARCHAR(200) NOT NULL, 8 GroupName NVARCHAR(200) NOT NULL, 9 Company NVARCHAR(300), 10 ModifiedDate datetime NOT NULL DEFAULT (getdate()) 11 ) 12 13 14 CREATE NONCLUSTERED INDEX NCL_Name_GroupName ON [dbo].[Department8](Name,[GroupName]) 15 16 DECLARE @i INT 17 SET @i=1 18 WHILE @i < 100 19 BEGIN 20 INSERT INTO Department8 ( name, [Company], groupname ) 21 VALUES ( '销售部'+CAST(@i AS VARCHAR(200)), '中国你好有限公司XX分公司', '销售组'+CAST(@i AS VARCHAR(200)) ) 22 SET @i = @i + 1 23 END 24 25 SELECT * FROM [dbo].[Department8] 26 27 --TRUNCATE TABLE [dbo].[DBCCResult] 28 INSERT INTO DBCCResult EXEC ('DBCC IND(pratice,Department8,-1) ') 29 30 SELECT * FROM [dbo].[DBCCResult] ORDER BY [PageType] DESC
先说明一下:
PageType 分页类型: 1:数据页面;2:索引页面;3:Lob_mixed_page;4:Lob_tree_page;10:IAM页面
IndexID 索引ID: 0 代表堆, 1 代表聚集索引, 2-250 代表非聚集索引 ,大于250就是text或image字段
每个数据页的IndexID都是0,说明数据页不属于非聚集索引的一部分,如果你有看到本系列的上篇,你会看到聚集索引表里数据页的IndexID都是1
说明数据页属于聚集索引的一部分,这里非聚集索引表的数据页的IndexID不是2而是0
-------------------------------------------------华丽的分割线--------------------------------------------------
下面看一下非聚集索引的索引页
1 DBCC TRACEON(3604,-1) 2 GO 3 DBCC PAGE([pratice],1,14499,3) 4 GO
聚集索引跟非聚集索引不同,聚集索引页里的一行表示一个数据页,而且标记了这个数据页索引字段的范围值
而非聚集索引跟数据表的记录一一对应,非聚集索引页里的一行记录表示数据表的一行记录,而且记录了指向实际记录的指针
其实非聚集索引的所有索引页合并在一起就是数据表的一个缩小版(表中只有非聚集索引),索引页中只包含创建非聚集索引时的字段,
所以当数据量少的时候,会使用全表扫描而不用索引扫描,因为堆中的数据页包含了表的全部字段 而索引页只包含了索引的字段,当select的时候
无论你是select * 还是select 某个字段 ,在效率上会差不多但是可以select出来的数据就会多很多
------------------------------------------------华丽的分割线--------------------------------------------------------------
那么非聚集索引是怎麽查找记录的?
这里分两种情况:(1)非聚集索引查找(2)非聚集索引扫描
这一次我就非聚集索引查找和非聚集索引扫描一起讲了,不像《SQLSERVER聚集索引与非聚集索引的再次研究(上)》里那样
查找和扫描分开来讲
这里创建Department9表,由于Department8表只有99行记录,数据量少的话SQLSERVER会直接走全表扫描,看不出效果
1 --非聚集索引 2 USE [pratice] 3 GO 4 5 CREATE TABLE Department9( 6 DepartmentID int IDENTITY(1,1) NOT NULL , 7 Name NVARCHAR(200) NOT NULL, 8 GroupName NVARCHAR(200) NOT NULL, 9 Company NVARCHAR(300), 10 ModifiedDate datetime NOT NULL DEFAULT (getdate()) 11 ) 12 13 14 CREATE NONCLUSTERED INDEX NCL_Name_GroupName ON [dbo].[Department9](Name,[GroupName]) 15 16 DECLARE @i INT 17 SET @i=1 18 WHILE @i < 1000000 19 BEGIN 20 INSERT INTO Department9 ( name, [Company], groupname ) 21 VALUES ( '销售部'+CAST(@i AS VARCHAR(200)), '中国你好有限公司XX分公司', '销售组'+CAST(@i AS VARCHAR(200)) ) 22 SET @i = @i + 1 23 END 24 25 SELECT * FROM [dbo].[Department9] 26 27 --TRUNCATE TABLE [dbo].[DBCCResult] 28 INSERT INTO DBCCResult EXEC ('DBCC IND(pratice,Department9,-1) ') 29 30 SELECT * FROM [dbo].[DBCCResult] ORDER BY [PageType] DESC