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 5 —— CSS概述

    CSS(Cascading Style Sheet)称为层叠样式表,也可以称为CSS样式表或样式表,其文件扩展名为.css,CSS是用于增强或控制网页样式,并允许将样式信息与网页内容分离的一种标记性语 ...

  2. CodeBblock 常用快捷键 (最常用)

    ==日常编辑== • 按住Ctrl滚滚轮,代码的字体会随你心意变大变小. • 在编辑区按住右键可拖动代码,省去拉(尤其是横向)滚动条之麻烦:相关设置:Mouse Drag Scrolling. • C ...

  3. IntelliJ IDEA 界面介绍及常用配置

    一:配置Maven File-->Settings-->搜索框输入maven -->配置maven home directory 跟 user setting file 二:配置JD ...

  4. centos7 memcached+magent+keepalived集群

    111,222均部署keepalived,magent,memcached keepalived 111为主机,222为备机 其中,111上magent以本地memcache为主,222为备用 222 ...

  5. npm webpack工具 (监听压缩等)

    压缩.监听变动自动打包,:开发后,js编译压缩及样式去空格等 $ webpack --config XXX.js //url使用另一份配置文件(比如webpack.config2.js)来打包 $ w ...

  6. Linux 4.10.8 根文件系统制作(二)---制作jiffs文件系统

    一.制作jiffs文件系统 制作jffs2 文件系统需要用到 mkfs.jffs2工具. 执行命令: mkfs.jffs2 -n -s 0x800 -e 0x20000  --pad=0x800000 ...

  7. luogu P2596 [ZJOI2006]书架

    传送门 感觉要死在\(Splay\)里了 orz 这题用\(Splay\)维护这个序列,其中的第\(k\)大点代表这个序列的第\(k\)个数 第一个操作,先把那个数所在的点旋到根,然后把整个根的左子树 ...

  8. sybench压测下模拟误truncate数据恢复

    基本环境:官方社区版MySQL 5.7.21 Row+Gtid开启sysbench压测,使用mysqldump备份数据库,执行truncate操作,恢复数据到truncate前的时间点1.切换日志,记 ...

  9. HTTP 协议报文解析

    说明转载自https://blog.csdn.net/chf1142152101/article/details/74162755 本篇主要是为了记录HTTP中报文的格式,以便针对报文进行解析.首先会 ...

  10. D - Searching the String (AC自动机)

    题目链接:https://cn.vjudge.net/contest/281961#problem/D 题目大意:给你一个模式串,然后给你多个匹配串,匹配串的类型是包括可以覆盖的以及不可覆盖的. 具体 ...