SqlServer索引碎片
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索引碎片的更多相关文章
- mssql sqlserver 索引专题
摘要: 下文将详细讲述sql server 索引的相关知识,如下所示: 实验环境: sql server 2008 R2 sqlserver索引简介: mssql sqlsever 索引分类简介 ms ...
- SQLServer中重建聚集索引之后会影响到非聚集索引的索引碎片吗
本文出处:http://www.cnblogs.com/wy123/p/7650215.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错 ...
- SqlServer 如何知道是否发生了索引碎片
--如何知道是否发生了索引碎片 SELECT object_name(dt.object_id) Tablename,si.name IndexName,dt.avg_fragmentation_in ...
- SQLServer 数据库索引碎片
--改成当前库 use DB_Name --创建变量 指定要查看的表 declare @table_id int set @table_id=object_id('TableName') --执行 d ...
- sqlserver索引小结
1.1 什么是索引? SQL索引有两种,聚集索引和非聚集索引,索引主要目的是提高了SQL Server系统的性能,加快数据的查询速度与减少系统的响应时间 下面举两个简单的例子: 图书馆的例子:一个图书 ...
- SQL Server2005索引碎片分析和解决方法
SQL Server2005索引碎片分析和解决方法 本文作者(郑贤娴),请您在阅读本文时尊重作者版权. 摘要: SQL Server,为了反应数据的更新,需要维护表上的索引,因而这些索引会形成碎片.根 ...
- 转:sql server索引碎片和解决方法
毫无疑问,给表添加索引是有好处的,你要做的大部分工作就是维护索引,在数据更改期间索引可能产生碎片,所以一些维护是必要的.碎片可能是你查询产生性能问题的来源. 那么到底什么是索引碎片呢?索引碎片实际上有 ...
- 提升SQL Server速度整理索引碎片
转载:http://wenku.baidu.com/view/f64c8a707fd5360cba1adbea.html SQL Server2005索引碎片分析和解决方法 毫无疑问,给表添加索引 ...
- sqlserver2008 如何定时清理索引碎片
sqlserver2008 如何定时清理索引碎片 查询索引引起的表垃圾碎片sql脚本: SELECT object_name(a.object_id) [TableName] ,a.index_id ...
随机推荐
- Study 8 —— 数据类型(列表/list)
列表是一个数据的集合,集合内可以放任何数据类型,可对集合进行方便的增删改查操作 1. 定义列表: 方法一: L1 = [] #定义空列表 L2 = ['A', 'B', 'C'] #存3个值,索引0 ...
- FZU 2254 英语考试
在过三个礼拜,YellowStar有一场专业英语考试,因此它必须着手开始复习. 这天,YellowStar准备了n个需要背的单词,每个单词的长度均为m. YellowSatr准备采用联想记忆法来背诵这 ...
- python -- 算法
给定四个数字,找出不重复的排列组合可能 # 黑魔法方法,还纳闷 lambda 不能 yield 其实把 [] 改为小括号即是生成器啦 func = lambda num_tuple:((i,j,k,n ...
- 【BZOJ2749】【HAOI2012】外星人[欧拉函数]
外星人 Time Limit: 3 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description Input Output 输出te ...
- <转载>iTerm2使用技巧
原文链接:http://www.cnblogs.com/756623607-zhang/p/7071281.html 1.设置窗口 定位到 [Preferences - Profiles - Wi ...
- Spring Boot 多模块项目创建与配置 (一) (转)
Spring Boot 多模块项目创建与配置 (一) 最近在负责的是一个比较复杂项目,模块很多,代码中的二级模块就有9个,部分二级模块下面还分了多个模块.代码中的多模块是用maven管理的,每个模块都 ...
- Linux 搭建 nexus 私服【转】
原文:https://yq.aliyun.com/articles/5981 第8章 私服nexus 本章详细介绍了nexus的安装过程,设置maven从私服下载构件,以及发布构件至nexus. 8. ...
- Linux Makefile 中的陷阱【转】
转自:https://blog.csdn.net/QQ1452008/article/details/52247944 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog. ...
- 使用Jyhon脚本和PMI模块监控WAS性能数据
使用Jyhon脚本和PMI模块监控WAS性能数据的优点有: 1.可以使用非交互的方式远程获取数据 2.不需要图形化模块支持 3.对各种was版本的兼容性较高 4.使用方便,官方自带 缺点也有很多: 1 ...
- Jenkins中配置selenium测试
Jenkins中配置selenium测试 2015/03/23 第一步在jenkins中配置selenium服务器 第二步工程配置: 第三步:执行构建: 第四步,查看报告: