示例代码:
use tempdb
go
drop table demo
go
create table demo (
a int,
b char(990))
go
create clustered index demo_index on demo (a)
go
--我们在表格里插入1000条记录。记录会占据125个页面。
declare @i int
set @i = 0
while @i < 1000
begin
insert into demo values (@i, 'abcd')
set @i = @i + 1
end
go
dbcc showcontig(demo)
go
DBCC SHOWCONTIG 正在扫描 'demo' 表...
表: 'demo' (165575628);索引 ID: 1,数据库 ID: 2
已执行 TABLE 级别的扫描。
- 扫描页数................................: 125------b为char(990),一行大概为1K字符,一页为8K,所以总插入大概为1000K,(125页)
- 扫描区数..............................: 21----一个区为64K,即8页。
- 区切换次数..............................: 21
- 每个区的平均页数........................: 6.0
- 扫描密度 [最佳计数:实际计数].......: 72.73% [16:22]
- 逻辑扫描碎片 ..................: 5.60%
- 区扫描碎片 ..................: 19.05%
- 每页的平均可用字节数........................: 72.0
- 平均页密度(满).....................: 99.11% 页密度很高,说明页面碎片少
DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。
--这时候页面里的大部分空间都是空闲的。通常我们说这种页面里碎片比较严重
declare @i numeric(6,2) --numeric 精度值
set @i=0
while @i<1000
begin
if @i/8<> convert(int ,@i/8)
delete demo where a=@i
set @i=@i+1
end
go
select * from demo
go
dbcc showcontig(demo)
DBCC SHOWCONTIG 正在扫描 'demo' 表...
表: 'demo' (165575628);索引 ID: 1,数据库 ID: 2
已执行 TABLE 级别的扫描。
- 扫描页数................................: 125
- 扫描区数..............................: 21
- 区切换次数..............................: 21
- 每个区的平均页数........................: 6.0
- 扫描密度 [最佳计数:实际计数].......: 72.73% [16:22]
- 逻辑扫描碎片 ..................: 5.60%
- 区扫描碎片 ..................: 19.05%
- 每页的平均可用字节数........................: 7093.0
- 平均页密度(满).....................: 12.37% 页面仍为125,而密度很低,说明碎片很多了
DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。
go
select * from demo
go
set statistics io off
go
--表 'demo'。扫描计数 1,逻辑读取 127 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
--只有125条记录,但是sql读取了127个页面
alter index ixdemoA on demo rebuild
go
set statistics io on
select * from demo
set statistics io off
--表 'demo'。扫描计数 1,逻辑读取 18 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
--索引重建后,只需18页了,节省6/7