关闭顶部展开顶部

怎样将索引碎片数量降至最低_Mssql数据库教程

编辑Tag赚U币
教程Tag:暂无Tag,欢迎添加,赚取U币!

推荐:SQL Server中, DateTime (日期)型操作的 SQL语法
这两天操作SQL Server的数据,需求是将一个日期类型字段的时、分、秒去处,即 ‘2007-11-07 16:41:35.033’ 改为‘2007-11-07 00:00:00‘,所以查询了一下网上对DateTime类型操作的SQL语法,发现实现这个功能很简单。 update YourTable set YourDateColumn

索引碎片能增大索引树的大小,增加不必要的IO,所以每隔一段时间对索引碎片进行检查时很有必要的。
下面一个示例一起来分析如何将索引降至最低。

新建一个表:
create table t3
(
i int primary key,
xx varchar(200) not null
)

加入数据:
declare @x int
set @x = 0while @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;
GO


BOL的推荐:
 

avg_fragmentation_in_percent修复语句

> 5% 且 < = 30%

ALTER INDEX REORGANIZE

> 30%

ALTER INDEX REBUILD WITH (ONLINE = ON)*

小于5没必要重建,所以上面的SQL语句还是有得商量的地方。

分享:解析Sqlserver常用函数
在操作SQLServer的时候, 很多时候记不住具体的函数如何使用, 查找联机帮助还是嫌麻烦, 且有很多时候例子也不好懂, 下面对每个常用的函数用用例子说明,一目了然,你自己在数据库中执行一下,结果就知道什么回事了 --字符串功能 --substring print substring('ia

来源:模板无忧//所属分类:Mssql数据库教程/更新时间:2010-05-27
loading.. 评论加载中....
相关Mssql数据库教程
闂佹眹鍩勯崹閬嶆偤閺囶澁缍栭柛鈩冪⊕閳锋帗銇勯弴妤€浜惧銈忕秶閹凤拷
濠电偛顕慨顓㈠磻閹炬枼妲堥柡鍌濇硶婢ф稒淇婇懠顒夆偓婵嬫煟閵忊晛鐏查柟鍑ゆ嫹
濠电姷顣介埀顒€鍟块埀顒勵棑缁辩偛顓兼径瀣閻庣懓瀚竟鍡欐崲娑斾線鏌i姀鈺佺伈闁瑰嚖鎷�
濠电姷顣介埀顒€鍟块埀顒勵棑缁辩偛顓兼径濠勵吋闂佽鍨庨崟顓фК闂佽閰eḿ褍螞濞戙垺鍋夐柨鐕傛嫹
闂備胶枪缁绘劙骞婃惔銊ョ劦妞ゆ帒鍊哥敮鍫曞箹鐎涙ḿ鐭掔€规洘绻堥弫鎾绘晸閿燂拷
闂備胶枪缁绘劙骞婃惔銊ョ劦妞ゆ巻鍋撻柛姘儑缁﹪鏁傞崜褏鐓撻柣搴岛閺呮繈鎯屽▎鎴犵=濞撴艾锕ョ€氾拷
闂備浇銆€閸嬫挻銇勯弽銊р槈闁伙富鍣i弻娑樷攽閹邦亞鑳虹紓浣靛妽濡炶棄顕i妸鈺婃晬婵炲棙鍨电粭锟犳⒑閸濆嫬鈧骞婇幘鑸殿潟闁跨噦鎷�
闂備礁鎼崯鐗堟叏妞嬪海绀婂鑸靛姈閻擄綁鎮规潪鎷岊劅婵炲眰鍊曢湁闁挎繂妫欑粈鈧梺鍛娚戦悧鐘茬暦閹扮増鏅搁柨鐕傛嫹
婵犵妲呴崹顏堝礈濠靛棭鐔嗘俊顖氬悑鐎氱粯銇勯幘瀵哥畺閻庢熬鎷�
濠电姷顣介埀顒€鍟块埀顒勵棑缁辩偛顓奸崶銊ヮ伕濡炪倖鎸荤换鍐偓姘虫珪娣囧﹪顢涘Δ鈧晶鍙夌節椤喗瀚�
婵犵妲呴崹顏堝礈濠靛棭鐔嗘慨妞诲亾鐎规洦鍓熼、娆撳礂閻撳簶鍋撻悽鍛婄厸闁割偅绻勫瓭婵犳鍣幏锟�
婵犵妲呴崹顏堝礈濠靛棭鐔嗘慨妞诲亾闁哄苯鎳橀崺鈧い鎺嗗亾闁宠閰i獮鎴﹀箛闂堟稒顔嗛梻浣告惈鐎氭悂骞忛敓锟�
婵犵妲呴崹顏堝礈濠靛棭鐔嗘慨妞诲亾鐎规洩缍侀獮瀣攽閸偂绱�
濠电姷顣介埀顒€鍟块埀顒勵棑缁辩偛顓兼径濠勭厬闂佺懓鐡ㄧ换鍕敂鐎涙ü绻嗘い鏍殔婢у弶绻濋~顔藉
闂佽楠搁崢婊堝礈濠靛鍋嬮柟鎯版閻鈹戦悩鎻掓殭闁奸潧缍婇弻銈夋嚍閵夈儱顫嶉梺缁樼壄缂嶄礁鐣峰▎鎾存櫢闁跨噦鎷�
UB闂備礁婀辩划顖炲礉濡ゅ懐宓侀柛銉㈡櫆鐎氭岸鎮楀☉娅虫垿锝為敓锟�
闂備浇澹堟ご绋款潖婵犳碍鐒鹃悗鐢电《閸嬫捇鐛崹顔句痪濠电姭鍋撻柨鐕傛嫹
闂佽楠哥粻宥夊垂閸濆嫸鑰块柛銏㈠殰
闂備礁鎲″缁樻叏妞嬪海绀婂璺虹灱閸楁碍绻涢崱妤€顒㈤柛鐐差槹缁绘稓绱欓悩鍝勫帯闂佺ǹ楠忛幏锟�
缂傚倸鍊烽悞锕傛偡閿曞倸鍨傛繝濠傚椤╅攱銇勯幒宥囶槮缂佹彃婀遍埀顒傚仯閸婃繄绱撳棰濇晩闁跨噦鎷�
©2017 www.mb5u.com婵犵妲呴崹顏堝礈濠靛棭鐔嗘慨妞诲亾鐎殿噮鍣i幃鈺呭箵閹烘挸鐦�
闂備浇銆€閸嬫捇鏌熼婊冾暭妞ゃ儻鎷�&闂備礁鎲$敮鎺懳涢弮鍫燁棅闁跨噦鎷�