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索引碎片的更多相关文章

  1. mssql sqlserver 索引专题

    摘要: 下文将详细讲述sql server 索引的相关知识,如下所示: 实验环境: sql server 2008 R2 sqlserver索引简介: mssql sqlsever 索引分类简介 ms ...

  2. SQLServer中重建聚集索引之后会影响到非聚集索引的索引碎片吗

    本文出处:http://www.cnblogs.com/wy123/p/7650215.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错 ...

  3. SqlServer 如何知道是否发生了索引碎片

    --如何知道是否发生了索引碎片 SELECT object_name(dt.object_id) Tablename,si.name IndexName,dt.avg_fragmentation_in ...

  4. SQLServer 数据库索引碎片

    --改成当前库 use DB_Name --创建变量 指定要查看的表 declare @table_id int set @table_id=object_id('TableName') --执行 d ...

  5. sqlserver索引小结

    1.1 什么是索引? SQL索引有两种,聚集索引和非聚集索引,索引主要目的是提高了SQL Server系统的性能,加快数据的查询速度与减少系统的响应时间 下面举两个简单的例子: 图书馆的例子:一个图书 ...

  6. SQL Server2005索引碎片分析和解决方法

    SQL Server2005索引碎片分析和解决方法 本文作者(郑贤娴),请您在阅读本文时尊重作者版权. 摘要: SQL Server,为了反应数据的更新,需要维护表上的索引,因而这些索引会形成碎片.根 ...

  7. 转:sql server索引碎片和解决方法

    毫无疑问,给表添加索引是有好处的,你要做的大部分工作就是维护索引,在数据更改期间索引可能产生碎片,所以一些维护是必要的.碎片可能是你查询产生性能问题的来源. 那么到底什么是索引碎片呢?索引碎片实际上有 ...

  8. 提升SQL Server速度整理索引碎片

    转载:http://wenku.baidu.com/view/f64c8a707fd5360cba1adbea.html SQL Server2005索引碎片分析和解决方法   毫无疑问,给表添加索引 ...

  9. sqlserver2008 如何定时清理索引碎片

    sqlserver2008 如何定时清理索引碎片 查询索引引起的表垃圾碎片sql脚本:  SELECT object_name(a.object_id) [TableName] ,a.index_id ...

随机推荐

  1. Study 8 —— 数据类型(列表/list)

    列表是一个数据的集合,集合内可以放任何数据类型,可对集合进行方便的增删改查操作 1. 定义列表: 方法一: L1 = [] #定义空列表 L2 = ['A', 'B', 'C']  #存3个值,索引0 ...

  2. FZU 2254 英语考试

    在过三个礼拜,YellowStar有一场专业英语考试,因此它必须着手开始复习. 这天,YellowStar准备了n个需要背的单词,每个单词的长度均为m. YellowSatr准备采用联想记忆法来背诵这 ...

  3. python -- 算法

    给定四个数字,找出不重复的排列组合可能 # 黑魔法方法,还纳闷 lambda 不能 yield 其实把 [] 改为小括号即是生成器啦 func = lambda num_tuple:((i,j,k,n ...

  4. 【BZOJ2749】【HAOI2012】外星人[欧拉函数]

    外星人 Time Limit: 3 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description Input   Output 输出te ...

  5. <转载>iTerm2使用技巧

    原文链接:http://www.cnblogs.com/756623607-zhang/p/7071281.html   1.设置窗口 定位到 [Preferences - Profiles - Wi ...

  6. Spring Boot 多模块项目创建与配置 (一) (转)

    Spring Boot 多模块项目创建与配置 (一) 最近在负责的是一个比较复杂项目,模块很多,代码中的二级模块就有9个,部分二级模块下面还分了多个模块.代码中的多模块是用maven管理的,每个模块都 ...

  7. Linux 搭建 nexus 私服【转】

    原文:https://yq.aliyun.com/articles/5981 第8章 私服nexus 本章详细介绍了nexus的安装过程,设置maven从私服下载构件,以及发布构件至nexus. 8. ...

  8. Linux Makefile 中的陷阱【转】

    转自:https://blog.csdn.net/QQ1452008/article/details/52247944 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog. ...

  9. 使用Jyhon脚本和PMI模块监控WAS性能数据

    使用Jyhon脚本和PMI模块监控WAS性能数据的优点有: 1.可以使用非交互的方式远程获取数据 2.不需要图形化模块支持 3.对各种was版本的兼容性较高 4.使用方便,官方自带 缺点也有很多: 1 ...

  10. Jenkins中配置selenium测试

    Jenkins中配置selenium测试 2015/03/23 第一步在jenkins中配置selenium服务器 第二步工程配置: 第三步:执行构建: 第四步,查看报告: