通过DBCC整理Sqlserver数据库表索引碎片
- 昨天检查了一张效率极慢的表,两年多没有维护,逻辑扫描碎片高达99.%,于是开始对这个表进行重点跟踪和记录日志。今天用DBCC SHOWCONTIG WITH TABLERESULTS 命令检查了一下所有表的概况,然后参照着MSDN对字段的说明,发现问题比较严重。ScanDensity(这是“最佳计数”与“实际计数”的比率。如果所有内容都是连续的,则该值为 ;如果该值小于 ,则存在一些碎片)有的甚至在16.,其他扫描密度等指标也特别不理想。
- 检查:
- 随便贴出一个表的扫描结果:
- --------------------------------------------------------------------------------------------------------------------------
- DBCC SHOWCONTIG 正在扫描 'UserInfo' 表...
- 表: 'UserInfo' ();索引 ID: ,数据库 ID:
- 已执行 TABLE 级别的扫描。
- - 扫描页数................................:
- - 扫描区数..............................:
- - 区切换次数..............................:
- - 每个区的平均页数........................: 7.6
- - 扫描密度 [最佳计数:实际计数].......: 12.92% [:]
- - 逻辑扫描碎片 ..................: 95.37%
- - 区扫描碎片 ..................: 47.92%
- - 每页的平均可用字节数.....................: 2996.8
- - 平均页密度(满).....................: 62.98%
- DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。
- --------------------------------------------------------------------------------------------------------------------------
- 解释如下( 查看解释来源点此 ,MSDN解释太官方,还是用简单点的话来解释):
- 扫描页数:如果你知道行的近似尺寸和表或索引里的行数,那么你可以估计出索引里的页数。看看扫描页数,如果明显比你估计的页数要高,说明存在内部碎片。
- 扫描扩展盘区数:用扫描页数除以8,四舍五入到下一个最高值。该值应该和DBCC SHOWCONTIG返回的扫描扩展盘区数一致。如果DBCC SHOWCONTIG返回的数高,说明存在外部碎片。碎片的严重程度依赖于刚才显示的值比估计值高多少。
- 扩展盘区开关数:该数应该等于扫描扩展盘区数减1。高了则说明有外部碎片。
- 每个扩展盘区上的平均页数:该数是扫描页数除以扫描扩展盘区数,一般是8。小于8说明有外部碎片。
- 扫描密度[最佳值:实际值]:DBCC SHOWCONTIG返回最有用的一个百分比。这是扩展盘区的最佳值和实际值的比率。该百分比应该尽可能靠近100%。低了则说明有外部碎片。
- 逻辑扫描碎片:无序页的百分比。该百分比应该在0%到10%之间,高了则说明有外部碎片。
- 扩展盘区扫描碎片:无序扩展盘区在扫描索引叶级页中所占的百分比。该百分比应该是0%,高了则说明有外部碎片。
- 每页上的平均可用字节数:所扫描的页上的平均可用字节数。越高说明有内部碎片,不过在你用这个数字决定是否有内部碎片之前,应该考虑fill factor(填充因子)。
- 平均页密度(完整):每页上的平均可用字节数的百分比的相反数。低的百分比说明有内部碎片。
- 整理数据库碎片索引
- 看到如此不对劲,果断去MSDN查找相关资料,找到了MSDN有对数据库索引进行碎片整理的T-SQL,执行了一下,发现效果还不错。
- 使用 DBCC SHOWCONTIG 和 DBCC INDEXDEFRAG 对数据库中的索引进行碎片整理:(以下示例将展示一种简单的方法,对数据库中碎片数量在声明的阈值之上的所有索引进行碎片整理。)
- /*Perform a 'USE <database name>' to select the database in which to run the script.*/
- -- Declare variables
- SET NOCOUNT ON;
- DECLARE @tablename varchar();
- DECLARE @execstr varchar();
- DECLARE @objectid int;
- DECLARE @indexid int;
- DECLARE @frag decimal;
- DECLARE @maxfrag decimal;
- -- Decide on the maximum fragmentation to allow for.
- SELECT @maxfrag = 30.0;
- -- Declare a cursor.
- DECLARE tables CURSOR FOR
- SELECT TABLE_SCHEMA + '.' + TABLE_NAME
- FROM INFORMATION_SCHEMA.TABLES
- WHERE TABLE_TYPE = 'BASE TABLE';
- -- Create the table.
- CREATE TABLE #fraglist (
- ObjectName char(),
- ObjectId int,
- IndexName char(),
- IndexId int,
- Lvl int,
- CountPages int,
- CountRows int,
- MinRecSize int,
- MaxRecSize int,
- AvgRecSize int,
- ForRecCount int,
- Extents int,
- ExtentSwitches int,
- AvgFreeBytes int,
- AvgPageDensity int,
- ScanDensity decimal,
- BestCount int,
- ActualCount int,
- LogicalFrag decimal,
- ExtentFrag decimal);
- -- Open the cursor.
- OPEN tables;
- -- Loop through all the tables in the database.
- FETCH NEXT
- FROM tables
- INTO @tablename;
- WHILE @@FETCH_STATUS =
- BEGIN;
- -- Do the showcontig of all indexes of the table
- INSERT INTO #fraglist
- EXEC ('DBCC SHOWCONTIG (''' + @tablename + ''')
- WITH FAST, TABLERESULTS, ALL_INDEXES, NO_INFOMSGS');
- FETCH NEXT
- FROM tables
- INTO @tablename;
- END;
- -- Close and deallocate the cursor.
- CLOSE tables;
- DEALLOCATE tables;
- -- Declare the cursor for the list of indexes to be defragged.
- DECLARE indexes CURSOR FOR
- SELECT ObjectName, ObjectId, IndexId, LogicalFrag
- FROM #fraglist
- WHERE LogicalFrag >= @maxfrag
- AND INDEXPROPERTY (ObjectId, IndexName, 'IndexDepth') > ;
- -- Open the cursor.
- OPEN indexes;
- -- Loop through the indexes.
- FETCH NEXT
- FROM indexes
- INTO @tablename, @objectid, @indexid, @frag;
- WHILE @@FETCH_STATUS =
- BEGIN;
- PRINT 'Executing DBCC INDEXDEFRAG (0, ' + RTRIM(@tablename) + ',
- ' + RTRIM(@indexid) + ') - fragmentation currently '
- + RTRIM(CONVERT(varchar(),@frag)) + '%';
- SELECT @execstr = 'DBCC INDEXDEFRAG (0, ' + RTRIM(@objectid) + ',
- ' + RTRIM(@indexid) + ')';
- EXEC (@execstr);
- FETCH NEXT
- FROM indexes
- INTO @tablename, @objectid, @indexid, @frag;
- END;
- -- Close and deallocate the cursor.
- CLOSE indexes;
- DEALLOCATE indexes;
- -- Delete the temporary table.
- DROP TABLE #fraglist;
- GO
- 执行后会返回索引扫描数、移动数、删除数(Pages Scanned、Pages Moved、Pages Removed)。效果还是很明显的,然后再把扫描结果进行比对:
- -----------------------------------------------------------------------------------------------------------------
- DBCC SHOWCONTIG 正在扫描 'UserInfo' 表...
- 表: 'UserInfo' ();索引 ID: ,数据库 ID:
- 已执行 TABLE 级别的扫描。
- - 扫描页数................................:
- - 扫描区数..............................:
- - 区切换次数..............................:
- - 每个区的平均页数........................: 7.6
- - 扫描密度 [最佳计数:实际计数].......: 96.77% [:]
- - 逻辑扫描碎片 ..................: 2.95%
- - 区扫描碎片 ..................: 29.03%
- - 每页的平均可用字节数.....................: 200.3
- - 平均页密度(满).....................: 97.52%
- DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系
- ------------------------------------------------------------------------------------------------------------
- 结果很有对比性,碎片大幅降低,每页的平均可用字节数大幅降低,扫描密度提高,平均页密度达到理想中的近饱和数值。看来DBCC的一些命令和MSDN的联机丛书还是很不错滴。虽然暂时降低了一些碎片指标,但只要有操作肯定也会有碎片产生,通过一段的时间跟踪,才能对整体情况进行主观的判断。
- 相关链接:http://msdn.microsoft.com/zh-cn/library/ms188796.aspx
- http://msdn.microsoft.com/zh-cn/library/ms175008(v=sql.90).aspx
通过DBCC整理Sqlserver数据库表索引碎片的更多相关文章
- SQLSERVER数据库表各种同步技术
1 --SQLSERVER数据库表各种同步技术 减少SQLServer中每次的同步数据量 2 3 --说到数据库,我就不由地想到同步数据,如何尽可能地减少每次的同步数据量,以此来提高同步效率,降低对网 ...
- SqlServer数据库表生成C# Model实体类SQL语句——补充
在sql语句最前边加上 use[数据库名] 原链接:https://www.cnblogs.com/jhli/p/11552105.html --[SQL骚操作]SqlServer数据库表生成C ...
- Oracle 数据库表空间碎片查询和整理
dba_free_space 显示的是有free 空间的tablespace ,如果一个tablespace 的free 空间不连续,那每段free空间都会在dba_free_space中存在一条记录 ...
- sql server 表索引碎片处理
DBCC SHOWCONTIG (Transact-SQL) SQL Server 2005 其他版本 更新日期: 2007 年 9 月 15 日 显示指定的表或视图的数据和索引的碎片信息. 重要提示 ...
- ms sqlserver数据库建索引
索引分类:从物理结构上可分为两种:聚集索引和非聚集索引 (此外还有空间索引.筛选索引.XML索引) 因为聚集索引是索引顺序与物理存储顺序一致,所以只能建一个. 聚集索引就是把数据按主键顺序存储: 因为 ...
- 用sql语句生成sqlserver数据库表的数据字典
THEN O.name ELSE N'' END, 表描述 THEN PTB.[value] END,N''), 字段序号=C.column_id, 字段名称=C.name, 字段描述=ISNULL( ...
- SqlServer数据库表导入SqlLite数据库表保持日期时间类型字段的格式
在写查询功能的过程中遇到一个这样的问题:按日期范围查询,sql语句是:where dt>=用户选择起始日期&&dt<=用户选择结束日期.数据库中的数据如图1,我选择的测试数 ...
- SAP中的数据库表索引
数据库表中的索引可以加快查询的速度.索引是数据库表字段的有序副本.附加的字段包含指向真实数据库表行的指针.排序可以使访问表行的速度变快,例如,可以使用二分搜索.数据库表至少有一个主索引,由它的key字 ...
- sqlserver 数据库表分区
参考文档 https://msdn.microsoft.com/zh-cn/library/ms345146(SQL.90).aspx http://blog.sina.com.cn/s/blog_4 ...
随机推荐
- android控件层次
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android=&q ...
- 教你管理SQL备份与恢复系列(1-20)
原链接:https://bbs.51cto.com/thread-1147908-1.html 教你备份与恢复数据库,直接下面下文档吧. 教你备份与恢复数据库(1)事务 http://bbs.51ct ...
- activiti--4----------------------------------流程变量
一.流程变量的作用 1.用来传递业务参数 2.指定连线完成任务(同意或拒绝) 3.动态指定任务办理人 二.测试代码块 Person类 package com.xingshang.processVari ...
- 用Visual Studio编辑Linux代码
估计很多人都是用惯了Visual Studio的主,怎么也不适应Linux的一套编辑器,比如vim.source insight这些东西,可视化的eclipse效果还好点,但一般以远程共享一台Linu ...
- PHP实现今天是星期几的几种写法
今天是星期几的写法有很多,本文整理了常用的三种. 代码如下: // 第一种写法 $da = date("w"); if( $da == "1" ){ ec ...
- LeetCode:贪婪算法
LeetCode:贪婪算法 贪婪算法基础 我 717. 1-bit and 2-bit Characters class Solution { public boolean isOneBitChara ...
- tomcat异常处理经验汇总
1.Https: Feb 21, 2018 5:22:02 PM org.apache.coyote.AbstractProtocol initSEVERE: Failed to initialize ...
- zabbix实现mysql数据库的监控(二)
上章我们把zabbix的服务端和客户端都部署完成了,本章接着进行两部分的设置: 1 添加对mysql数据库主机的监控 2 添加对mysql数据库的监控 一.对数据库服务器主机监控 1 创建主机 步 ...
- day3--集合、文件操作、字符编码与转换、函数(递归,lambda,filter,map)、字典排序
list1 = set([1, 2, 3, 4, 5, 6, 5, 5, 5])list2 = set([11, 2, 36, 'a', 5, 6, 5, 5, 5])list3 = set([1, ...
- 蓝牙通讯 ble
http://blog.csdn.net/beijingshi1/article/details/36426829