昨天检查了一张效率极慢的表,两年多没有维护,逻辑扫描碎片高达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数据库表索引碎片的更多相关文章

  1. SQLSERVER数据库表各种同步技术

    1 --SQLSERVER数据库表各种同步技术 减少SQLServer中每次的同步数据量 2 3 --说到数据库,我就不由地想到同步数据,如何尽可能地减少每次的同步数据量,以此来提高同步效率,降低对网 ...

  2. SqlServer数据库表生成C# Model实体类SQL语句——补充

    在sql语句最前边加上  use[数据库名] 原链接:https://www.cnblogs.com/jhli/p/11552105.html   --[SQL骚操作]SqlServer数据库表生成C ...

  3. Oracle 数据库表空间碎片查询和整理

    dba_free_space 显示的是有free 空间的tablespace ,如果一个tablespace 的free 空间不连续,那每段free空间都会在dba_free_space中存在一条记录 ...

  4. sql server 表索引碎片处理

    DBCC SHOWCONTIG (Transact-SQL) SQL Server 2005 其他版本 更新日期: 2007 年 9 月 15 日 显示指定的表或视图的数据和索引的碎片信息. 重要提示 ...

  5. ms sqlserver数据库建索引

    索引分类:从物理结构上可分为两种:聚集索引和非聚集索引 (此外还有空间索引.筛选索引.XML索引) 因为聚集索引是索引顺序与物理存储顺序一致,所以只能建一个. 聚集索引就是把数据按主键顺序存储: 因为 ...

  6. 用sql语句生成sqlserver数据库表的数据字典

    THEN O.name ELSE N'' END, 表描述 THEN PTB.[value] END,N''), 字段序号=C.column_id, 字段名称=C.name, 字段描述=ISNULL( ...

  7. SqlServer数据库表导入SqlLite数据库表保持日期时间类型字段的格式

    在写查询功能的过程中遇到一个这样的问题:按日期范围查询,sql语句是:where dt>=用户选择起始日期&&dt<=用户选择结束日期.数据库中的数据如图1,我选择的测试数 ...

  8. SAP中的数据库表索引

    数据库表中的索引可以加快查询的速度.索引是数据库表字段的有序副本.附加的字段包含指向真实数据库表行的指针.排序可以使访问表行的速度变快,例如,可以使用二分搜索.数据库表至少有一个主索引,由它的key字 ...

  9. sqlserver 数据库表分区

    参考文档 https://msdn.microsoft.com/zh-cn/library/ms345146(SQL.90).aspx http://blog.sina.com.cn/s/blog_4 ...

随机推荐

  1. linux c编程:进程控制(一)

    一个进程,包括代码.数据和分配给进程的资源.fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程, 也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同 ...

  2. Excel控制IE

    ---恢复内容开始--- 1.初始化and连接http网页 Set ie = CreateObject("InternetExplorer.Application") ie.Vis ...

  3. Android Studio support 26.0.0-alpha1 Failed to resolve: com.android.support:appcompat-v7:27.+ 报错解决方法

    AS下如何生成自定义的.jks签名文件, 以及如何生成数字签名 链接:http://www.cnblogs.com/smyhvae/p/4456420.html 链接:http://blog.csdn ...

  4. QCon2016 上海会议汇总(2) - 团队管理

    QCon 2016上海日程:http://2016.qconshanghai.com/schedule <当你的团队还支撑不起梦想时> - 链尚网技术合伙人 杨荣伟 Figo讲述了如何训练 ...

  5. TF linear regression

    本文的作者 Nishant Shukla 为加州大学洛杉矶分校的机器视觉研究者,从事研究机器人机器学习技术.Nishant Shukla 一直以来兼任 Microsoft.Facebook 和 Fou ...

  6. c的详细学习(5)数组

        到目前为止,前面介绍的都是属于基本类型的数据.除此之外,C语言还提供了一些更为复杂的数据类型,称为构造类型.数组就是最基本的构造类型.若要针对一批数据进行某种操作,采用数组是一种方便可行的方法 ...

  7. 尽量不要在viewWillDisappear:方法中移除通知

    1.iOS7新增加了导航控制器侧滑手势,当触发侧滑返回时,会调用系统的viewWillDisappear:方法,取消侧滑返回时又会调用viewWillAppear:方法.   2.在做手势和通知等一系 ...

  8. linux通过脚本获取内存信息

    1 原理 脚本中通过执行free获取内存信息,然后将文本信息通过“空格”分隔符分割成字符串数组将不同信息提取出来,最后通过bc计算出百分比 2 脚本 #!/bin/shHOSTNAME=`hostna ...

  9. Android进程间通信(IPC)机制Binder简要介绍和学习计划【转】

    本文转载自:http://blog.csdn.net/luoshengyang/article/details/6618363 在Android系统中,每一个应用程序都是由一些Activity和Ser ...

  10. dbgrid,datasoure,ClientDataSet的简单应用

    dbgrid是用来在界面上显示数据的,需要连接源dbgrid1.datasource := datasource1; datasource:作为dbgrid,clientDataset的连接桥梁,需要 ...