[转]SQL SERVER整理索引碎片测试
SQL SERVER整理索引碎片测试
SQL SERVER整理索引的方法也就这么几种,而且老是自作聪明的加入智能判断很不爽,还是比DBMS_ADVISOR差远了:
1
SQL SERVER 2000/2005
查询
| 2000 use DB_Name declare @table_id int set @table_id=object_id('Table_Name') dbcc showcontig(@table_id) 2005 |
整理
| 2000 DBCC INDEXDEFRAG (DB_Name, 'dbo.Table_Name', Index_Name) DBCC DBREINDEX ('DB_Name.dbo.Table_Name','',100) 2005 |
以下是一个网上找的不错的例子,链接是:
http://www.cnblogs.com/perfectdesign/archive/2008/02/20/sqlserverreindexrebuild.html
新建一个表:
create table t3
(
i int primary key,
xx varchar(200) not null
)加入数据:
declare @x int
set @x = 0
while @x <1000
begin
insert into t3 values (@x,'qweasdqweasdqweasdqweqweasdqwe')
set @x = @x+1
end执行动态管理视图:
SELECT index_id,index_type_desc,avg_fragmentation_in_percent,page_count FROM sys.dm_db_index_physical_stats
(db_id(), OBJECT_ID('t3'), NULL, NULL , 'LIMITED');

可以看到:
index_id为0表示这个是堆,平均的碎片有33%
现在执行几个可以减少碎片的方法都不管用,不能减少碎片。
包括:
DBCC INDEXDEFRAG (test, 'dbo.t3', PK__t3__0EA330E9)
alter index PK__t3__0EA330E9 on t3
rebuild
dbcc dbreindex ('t3')
这几个方法还有删除重建索引,都不能减少碎片数量。
后来我觉得是因为数据太少了,导致页也很少,数据库可能存在某种智能,判断是否值得去做重建索引的工作,所以加大的数据量:
declare @x int
set @x = 1000
while @x <10000
begin
insert into t3 values (@x,'qweasdqweasdqweasdqweqweasdqwe')
set @x = @x+1
end再执行语句:
SELECT index_id,index_type_desc,avg_fragmentation_in_percent,page_count FROM sys.dm_db_index_physical_stats
(db_id(), OBJECT_ID('t3'), NULL, NULL , 'LIMITED');

alter index t3index on t3 rebuild
显示出来了!
结论:
SQL Server在执行相关的操作的时候都会智能去判断是否值得去做,比如在页面数太小的情况下可以不去重建索引,rebuild reindex 。类似的,在SQL Server 2005 里面也多了许多智能的判断来保证一个完整庞大而又不失智能的设计,
比如:
生成查询计划的阀值
缓存机制,缓存的筛选,LRU算法
预读机制
checkpoint减少回滚距离
智能join判断
重编译
了解SQL Server这种类似的软件产品能够为我们在设计产品的时候提供更多的思路想法,即使你了解上面的东西对你的SQL开发也不会有太多帮助。
另外附上几种方式的区别:
reindex是比较好的选择,速度快,但是他不能在线操作
INDEXDEFRAG 比较慢,但是可以在线操作
rebuild建议在碎片较少时采用。
附上微软的重建索引脚本,从里面也可以看出微软根据碎片大小推荐的方式,不过这个要随每个不同的数据库而定。
-- ensure a USE <databasename> statement has been executed first.
SET NOCOUNT ON;
DECLARE @objectid int;
DECLARE @indexid int;
DECLARE @partitioncount bigint;
DECLARE @schemaname sysname;
DECLARE @objectname sysname;
DECLARE @indexname sysname;
DECLARE @partitionnum bigint;
DECLARE @partitions bigint;
DECLARE @frag float;
DECLARE @command varchar(8000);
-- ensure the temporary table does not exist
IF EXISTS (SELECT name FROM sys.objects WHERE name = 'work_to_do')
DROP TABLE work_to_do;
-- conditionally select from the function, converting object and index IDs to names.
SELECT
object_id AS objectid,
index_id AS indexid,
partition_number AS partitionnum,
avg_fragmentation_in_percent AS frag
INTO work_to_do
FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, 'LIMITED')
WHERE avg_fragmentation_in_percent > 10.0 AND index_id > 0;
-- Declare the cursor for the list of partitions to be processed.
DECLARE partitions CURSOR FOR SELECT * FROM work_to_do;
-- Open the cursor.
OPEN partitions;
-- Loop through the partitions.
FETCH NEXT
FROM partitions
INTO @objectid, @indexid, @partitionnum, @frag;
WHILE @@FETCH_STATUS = 0
BEGIN;
SELECT @objectname = o.name, @schemaname = s.name
FROM sys.objects AS o
JOIN sys.schemas as s ON s.schema_id = o.schema_id
WHERE o.object_id = @objectid;
SELECT @indexname = name
FROM sys.indexes
WHERE object_id = @objectid AND index_id = @indexid;
SELECT @partitioncount = count (*)
FROM sys.partitions
WHERE object_id = @objectid AND index_id = @indexid;
-- 30 is an arbitrary decision point at which to switch between reorganizing and rebuilding
IF @frag < 30.0
BEGIN;
SELECT @command = 'ALTER INDEX ' + @indexname + ' ON ' + @schemaname + '.' + @objectname + ' REORGANIZE';
IF @partitioncount > 1
SELECT @command = @command + ' PARTITION=' + CONVERT (CHAR, @partitionnum);
EXEC (@command);
END;
IF @frag >= 30.0
BEGIN;
SELECT @command = 'ALTER INDEX ' + @indexname +' ON ' + @schemaname + '.' + @objectname + ' REBUILD';
IF @partitioncount > 1
SELECT @command = @command + ' PARTITION=' + CONVERT (CHAR, @partitionnum);
EXEC (@command);
END;
PRINT 'Executed ' + @command;
FETCH NEXT FROM partitions INTO @objectid, @indexid, @partitionnum, @frag;
END;
-- Close and deallocate the cursor.
CLOSE partitions;
DEALLOCATE partitions;
-- drop the temporary table
IF EXISTS (SELECT name FROM sys.objects WHERE name = 'work_to_do')
DROP TABLE work_to_do;
GOBOL的推荐:
| avg_fragmentation_in_percent 值 | 修复语句 |
|---|---|
|
> 5% 且 < = 30% |
ALTER INDEX REORGANIZE |
|
> 30% |
ALTER INDEX REBUILD WITH (ONLINE = ON)* |
小于5没必要重建,所以上面的SQL语句还是有得商量的地方。
http://blog.csdn.net/greenery/archive/2008/08/06/2778486.aspx
|
SET NOCOUNT ON DECLARE @MaxScanDensity DECIMAL--扫描密度 DECLARE @Page INT --8k页数,设定一个限度对一定大的索引进行整理 DECLARE @TmpName VARCHAR(150) -- Decide on the maximum fragmentation to allow SELECT @maxfrag = 30.0 -- Declare cursor DECLARE tables CURSOR FOR -- Create the table CREATE TABLE #fraglist ( -- Open the cursor OPEN tables -- Loop through all the tables in the database FETCH NEXT WHILE @@FETCH_STATUS = 0 INSERT INTO #fraglist -- Close and deallocate the cursor CLOSE tables -- Declare cursor for list of indexes to be defragged DECLARE indexes CURSOR FOR -- Open the cursor OPEN indexes -- loop through the indexes FETCH NEXT WHILE @@FETCH_STATUS = 0 PRINT 'Executing DBCC INDEXDEFRAG (0, ' + RTRIM(@tablename) + ', IF @TmpName<>@tablename -- Close and deallocate the cursor CLOSE indexes -- Delete the temporary table DROP TABLE #fraglist END GO |
[转]SQL SERVER整理索引碎片测试的更多相关文章
- sql server 表索引碎片处理
DBCC SHOWCONTIG (Transact-SQL) SQL Server 2005 其他版本 更新日期: 2007 年 9 月 15 日 显示指定的表或视图的数据和索引的碎片信息. 重要提示 ...
- sql server 查看索引碎片大小,并定期重建索引
查看碎片情况使用 dbcc showcontig 函数来进行 代码: --改成当前库 use DB_Name --创建变量 指定要查看的表 declare @table_id int set @ ...
- 改进SQL Server 性能 - 索引碎片重建
我们先来看一个用户表上的索引碎片情况: DBCC SHOWCONTIG scanning 'Lead' table...Table: 'Lead' (1422628111); index ID: 1, ...
- SQL Server清理索引碎片
DECLARE @SchemeName NVARCHAR(MAX)=N''; DECLARE @TableName NVARCHAR(MAX)=N''; DECLARE @IndexName NVAR ...
- 提升SQL Server速度整理索引碎片
转载:http://wenku.baidu.com/view/f64c8a707fd5360cba1adbea.html SQL Server2005索引碎片分析和解决方法 毫无疑问,给表添加索引 ...
- SQL Server通过整理索引碎片和重建索引提高速度
本文章转载:http://database.51cto.com/art/201108/282408.htm SQL Server数据库中,当索引碎片太多时,就会拖慢数据库查询的速度.这时我们可以通过整 ...
- [转]整理索引碎片,提升SQL Server速度
数据库表A有十万条记录,查询速度本来还可以,但导入一千条数据后,问题出现了.当选择的数据在原十万条记录之间时,速度还是挺快的:但当选择的数据在这一千条数据之间时,速度变得奇慢. 凭经验,这是索引碎片问 ...
- SQL Server 查询优化 索引的结构与分类
一.索引的结构 关系型数据库中以二维表来表达关系模型,表中的数据以页的形式存储在磁盘上,在SQL SERVER中,数据页是磁盘上8k的连续空间,那么,一个表的所有数据页在磁盘上是如何组织的呢?分两种情 ...
- SQL Server-索引管理
http://www.2cto.com/database/201305/207508.html SQL Server-索引管理 一.显示索引信息 在建立索引后,可以对表索引信息进行查询. (1)在 ...
随机推荐
- java导出excel模板数据
Java导出excel数据模板,这里直接贴代码开发,流程性的走下去就是步骤: String[] colName=new String[]{"期间","科目代码" ...
- 吴裕雄 python深度学习与实践(10)
import tensorflow as tf input1 = tf.constant(1) print(input1) input2 = tf.Variable(2,tf.int32) print ...
- m3u8文件什么合成便于播放的MP4的方法
先大家要知道M3U8文件不是一个视频文件,里面全是一些路径,说白了就是一个目录而已,所以要看视频,要找到对应存放视频的文件夹.如果不知道怎么找,可以使用文本格式打开M3U8文件,里面会有路径提示. ...
- 第一个只出现一次的字符字符(python)
题目描述 在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写). # -*- codin ...
- 20175314 《Java程序设计》第四周学习总结
20175314 <Java程序设计>第四周学习总结 教材学习内容总结 每个子类只能有一个父类,而一个父类可以有多个子类.可以使用关键字extends来定义一个类的子类:class 子类名 ...
- [leetcode]3. Longest Substring Without Repeating Characters无重复字母的最长子串
Given a string, find the length of the longest substring without repeating characters. Examples: Giv ...
- zabbix邮件自动预警
Zabbix报警 自定义脚本报警 报警大致过程 item数据采集--->触发器由阈值触发带级别的信息-->触发动作发送邮件预警 1. 发送邮件脚本 1)安装sendEmail(参考Linu ...
- TUN/TAP编程实现
其实关于这两种设备的编程,基本上属于八股文,大家一般都这么干. 启动设备之前 有的linux 并没有将tun 模块编译到内核之中,所以,我们要做的第一件事情就是检查我们的系统是否支持 TUN/TAP ...
- 17. pt-online-schema-change
在平时MySQL的运维过程中,经常会遇到表结构的变更.在表比较小的时候,直接进行变更,时间较短,但是当表非常大的时候,这么做会导致应用卡死,服务不可用.目前InnoDB引擎是通过以下步骤来进行DDL的 ...
- python 05集合
1.集合 特性:可变的,不同元素组成,无序,集合中元素类型必须是不可变(数字,元组,字符串) 形式:s={1,"good",(2,3)} 方法:add(), clear()清空, ...