码迷,mamicode.com
首页 > 数据库 > 详细

SqlServer索引碎片

时间:2017-08-21 18:54:18      阅读:258      评论:0      收藏:0      [点我收藏+]

标签:产生   eve   div   database   自动   constrain   收缩   dbcc   identity   

1.产生碎片的操作

通过sys.dm_index_physical_stats来查看,索引上的页不在具有连续性时就会产生碎片,碎片是索引上页拆分的物理结果。

(1).插入操作:

INSERT操作在聚集索引和非聚集索引上都可以引起碎片

使用业务键或者GUID等类型 做聚集索引,很容易产生碎片

代码如下:

 IF OBJECT_ID(‘dbo.Table_GUID‘) IS NOT NULL
DROP TABLE dbo.Table_GUID;
CREATE TABLE Table_GUID
(
RowID UNIQUEIDENTIFIER CONSTRAINT DF_GUIDValue DEFAULT NEWID(),--使用GUID作为默认值
Name sysname,
Value VARCHAR(2000)
);

--插入数据,注意此时还没有创建聚集索引
INSERT INTO dbo.Table_GUID(  Name, Value )
		SELECT name,REPLICATE(‘X‘,2000)
		 FROM sys.columns


		 SELECT * FROM dbo.Table_GUID
--在列上创建聚集索引
CREATE CLUSTERED INDEX CLUS_UsingUniqueidentifer ON dbo.Table_GUID(RowID);

--查看平均碎片
SELECT index_type_desc,
index_depth,
index_level,
page_count,
record_count,
CAST(avg_fragmentation_in_percent AS DECIMAL(6,2)) AS avg_fragmentation_in_percent,
fragment_count,
avg_fragment_size_in_pages,
CAST(avg_page_space_used_in_percent AS DECIMAL(6,2)) AS avg_page_space_used_in_percent
 FROM sys.dm_db_index_physical_stats(DB_ID(),OBJECT_ID(N‘dbo.Table_GUID‘),NULL,NULL,‘DETAILED‘)

 技术分享

平均碎片为0,插入后才建索引。

插入数据:

 --插入新数据
 INSERT INTO dbo.Table_GUID
         (  Name, Value )
SELECT name, REPLICATE(‘X‘,2000) FROM sys.objects

 查看索引碎片:

--查看平均碎片
SELECT index_type_desc,
index_depth,
index_level,
page_count,
record_count,
CAST(avg_fragmentation_in_percent AS DECIMAL(6,2)) AS avg_fragmentation_in_percent,
fragment_count,
avg_fragment_size_in_pages,
CAST(avg_page_space_used_in_percent AS DECIMAL(6,2)) AS avg_page_space_used_in_percent
 FROM sys.dm_db_index_physical_stats(DB_ID(),OBJECT_ID(N‘dbo.Table_GUID‘),NULL,NULL,‘DETAILED‘)

 技术分享

非聚集索引:

 CREATE NONCLUSTERED INDEX IX_Name ON dbo.Table_GUID(Name) INCLUDE(Value)

 执行以上两次操作。

技术分享

由此可见:当INSERT操作发生时,产生碎片再所难免,唯一要做的是尽可能降低碎片的产生速率。

(2):更新操作

 --跟新操作
  IF OBJECT_ID(‘dbo.Update_Fr‘) IS NOT NULL
DROP TABLE dbo.Update_Fr;
CREATE TABLE Update_Fr
(
RowID INT IDENTITY(1,1),--使用GUID作为默认值
Name sysname,
Value VARCHAR(2000)
);

INSERT INTO dbo.Update_Fr
        (  Name, Value )
		SELECT name,REPLICATE(‘X‘,1000)
 FROM sys.columns

 CREATE CLUSTERED INDEX CLUS_UsingUniqueidentifier ON dbo.Update_Fr(RowID);

 --检查一下空间
SELECT index_type_desc,
index_depth,
index_level,
page_count,
record_count,
CAST(avg_fragmentation_in_percent AS DECIMAL(6,2)) AS avg_fragmentation_in_percent,
fragment_count,
avg_fragment_size_in_pages,
CAST(avg_page_space_used_in_percent AS DECIMAL(6,2)) AS avg_page_space_used_in_percent
 FROM sys.dm_db_index_physical_stats(DB_ID(),OBJECT_ID(N‘dbo.Update_Fr‘),NULL,NULL,‘DETAILED‘)

 技术分享

 

--更新数据让长度变长
 UPDATE dbo.Update_Fr SET Value=REPLICATE(‘X‘,2000)
 WHERE RowID % 5=1

技术分享

 

键值的改变导致碎片的产生:

 --创建一个非聚集索引
 CREATE NONCLUSTERED INDEX IX_Name ON dbo.Update_Fr(Name) INCLUDE (Value);

 --通过REVERST函数把名称反转监控跟新前后的碎片情况
SELECT index_type_desc,
index_depth,
index_level,
page_count,
record_count,
CAST(avg_fragmentation_in_percent AS DECIMAL(6,2)) AS avg_fragmentation_in_percent,
fragment_count,
avg_fragment_size_in_pages,
CAST(avg_page_space_used_in_percent AS DECIMAL(6,2)) AS avg_page_space_used_in_percent
 FROM sys.dm_db_index_physical_stats(DB_ID(),OBJECT_ID(N‘dbo.Update_Fr‘),NULL,NULL,‘DETAILED‘)

 技术分享

 


 --通过REVERST函数把名称反转监控跟新前后的碎片情况

UPDATE dbo.Update_Fr
 SET Name=REVERSE(Name)
 WHERE RowID%9=1

 SELECT index_type_desc,
index_depth,
index_level,
page_count,
record_count,
CAST(avg_fragmentation_in_percent AS DECIMAL(6,2)) AS avg_fragmentation_in_percent,
fragment_count,
avg_fragment_size_in_pages,
CAST(avg_page_space_used_in_percent AS DECIMAL(6,2)) AS avg_page_space_used_in_percent
 FROM sys.dm_db_index_physical_stats(DB_ID(),OBJECT_ID(N‘dbo.Update_Fr‘),NULL,NULL,‘DETAILED‘)

 技术分享

 

(3).收缩操作:

 

 IF DB_ID(N‘Fragmentation‘) IS NOT NULL
 DROP DATABASE Fragmentation
 CREATE DATABASE Fragmentation
  USE Fragmentation

  IF OBJECT_ID(‘dbo.FirstTable‘) IS NOT NULL
DROP TABLE dbo.FirstTable;

CREATE TABLE dbo.FirstTable
(
RowID INT IDENTITY(1,1),
Name sysname,
Value VARCHAR(2000),
CONSTRAINT PK_FirstTable PRIMARY KEY CLUSTERED(RowID)
);

INSERT INTO dbo.FirstTable
        (  Name, Value )
SELECT name,REPLICATE(‘X‘,2000) FROM sys.columns



 IF OBJECT_ID(‘dbo.SecondTable‘) IS NOT NULL
DROP TABLE dbo.SecondTable;

CREATE TABLE dbo.SecondTable
(
RowID INT IDENTITY(1,1),
Name sysname,
Value VARCHAR(2000),
CONSTRAINT PK_SecondTable PRIMARY KEY CLUSTERED(RowID)
);

INSERT INTO dbo.SecondTable
        (  Name, Value )
SELECT name,REPLICATE(‘X‘,2000) FROM sys.columns


INSERT INTO dbo.FirstTable
        (  Name, Value )
SELECT name,REPLICATE(‘X‘,2000) FROM sys.columns


INSERT INTO dbo.SecondTable
        (  Name, Value )
SELECT name,REPLICATE(‘X‘,2000) FROM sys.columns


INSERT INTO dbo.FirstTable
        (  Name, Value )
SELECT name,REPLICATE(‘X‘,2000) FROM sys.columns


 SELECT index_type_desc,
index_depth,
index_level,
page_count,
record_count,
CAST(avg_fragmentation_in_percent AS DECIMAL(6,2)) AS avg_fragmentation_in_percent,
fragment_count,
avg_fragment_size_in_pages,
CAST(avg_page_space_used_in_percent AS DECIMAL(6,2)) AS avg_page_space_used_in_percent
 FROM sys.dm_db_index_physical_stats(DB_ID(),OBJECT_ID(N‘dbo.FirstTable‘),NULL,NULL,‘DETAILED‘)


 
 IF OBJECT_ID(‘dbo.SecondTable‘) IS NOT NULL
DROP TABLE dbo.SecondTable;

 SELECT index_type_desc,
index_depth,
index_level,
page_count,
record_count,
CAST(avg_fragmentation_in_percent AS DECIMAL(6,2)) AS avg_fragmentation_in_percent,
fragment_count,
avg_fragment_size_in_pages,
CAST(avg_page_space_used_in_percent AS DECIMAL(6,2)) AS avg_page_space_used_in_percent
 FROM sys.dm_db_index_physical_stats(DB_ID(),OBJECT_ID(N‘dbo.FirstTable‘),NULL,NULL,‘DETAILED‘)

技术分享

技术分享

删除前后的索引碎片一样。

由于SqlServer不会自动回收,调用DBCC SHRINKDATABASE来收缩数据库,再次查看碎片情况。

 DBCC SHRINKDATABASE(Fragmentation)

 技术分享

再次查看碎片:

技术分享

所以自动收缩数据不建议使用。

 

SqlServer索引碎片

标签:产生   eve   div   database   自动   constrain   收缩   dbcc   identity   

原文地址:http://www.cnblogs.com/sunliyuan/p/7405952.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!