创建聚集索引并重新组织
CREATE UNIQUE CLUSTERED INDEX CIX_Employee001_Id ON Employee001(Id);
ALTER INDEX CIX_Employee001_Id ON Employee001 REORGANIZE;
索引情况
SELECT
database_id,
index_id,
index_type_desc,
index_depth,
index_level,
page_count
FROM sys.dm_db_index_physical_stats(DB_ID(‘IndexDB‘),OBJECT_ID(‘Employee001‘),null,null,null)
只有一个聚集索引,索引深度为3(两级聚集索引页+一级数据页),数据页数量为1615
重新查询页信息
TRUNCATE TABLE DBCCIndResult
INSERT INTO DBCCIndResult EXEC(‘DBCC IND(IndexDB,Employee001,-1)‘)
与02.索引-堆表中相比 多了一些PageType=2的页(索引页)
并且 数据页的数量变少了(1615个,不一定变少,只是可能存数据页数量不一样的情况)
同事页编号也改变了(由于需要生成聚集索引,数据页也会被重新组织,按照索引键列排序)
根据查询出的索引非叶子节点的信息,索引页有两种IndexLevel
IndexLevel=2 是根节点 IndexLevel是中间节点
IndexLevel=0肯定是数据页节点
从根节点的索引页开始看
DBCC TRACEON(3604)
DBCC PAGE (IndexDB, 1, 2162, 3);
共有16行数据,指向16个中间索引页(PageType=2,IndexLevel=1),
选择一个中间索引页查看
由于是最后一层索引页(由于数据量只有10W,因此只建立了2 Level的索引),因此数据行指向 数据页
选择一个数据页查看
DBCC TRACEON(3604)
DBCC PAGE (IndexDB, 1, 2260, 3) WITH TABLERESULTS;
将数据插入到表中,方便查询
--查看分页情况
SELECT * FROM DBCCIndResult
--查看页的详细数据
DBCC TRACEON(3604)
TRUNCATE TABLE DBCCPageResult
--选中一页 例如 145页
INSERT INTO DBCCPageResult EXEC (‘DBCC PAGE (IndexDB, 1, 2260, 3) WITH TABLERESULTS‘)
SELECT * FROM DBCCPageResult
WHERE Field IN(‘Id‘)
可以看到Id列(聚集索引列)是按照排序排好的
查询数据,打开IO和执行计划
SET STATISTICS IO ON
SELECT Name From Employee001
WHERE Id= ‘43107053D74E484EB02B5B395178F682‘
与02.索引-堆表中(没有任何索引)相同的查询对比
执行计划为 Clustered Index Seek
只有三次逻辑读取(根据树的查找方式可以推断,三次读取分别为根索引页,一个IndexLevel=1的索引页,一个数据页)
可以进一步证明,使用下面的语句查看查询过程中使用了哪些资源:
USE [IndexDB]
GO
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
GO
BEGIN TRAN
SET STATISTICS IO ON
SELECT Name From Employee001
WHERE Id= ‘43107053D74E484EB02B5B395178F682‘
SET STATISTICS IO OFF
USE [IndexDB] --要查询申请锁的数据库
GO
SELECT
[request_session_id],
c.[program_name],
DB_NAME(c.[dbid]) AS dbname,
[resource_type],
[request_status],
[request_mode],
[resource_description],OBJECT_NAME(p.[object_id]) AS objectname,
p.[index_id]
FROM sys.[dm_tran_locks] AS a LEFT JOIN sys.[partitions] AS p
ON a.[resource_associated_entity_id]=p.[hobt_id]
LEFT JOIN sys.[sysprocesses] AS c ON a.[request_session_id]=c.[spid]
WHERE c.[dbid]=DB_ID(‘IndexDB‘) AND a.[request_session_id]=@@SPID
ORDER BY [request_session_id],[resource_type]
COMMIT TRAN