国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > SQL Server > 正文

怎樣將索引碎片數量降至最低

2024-08-31 00:46:59
字體:
來源:轉載
供稿:網友
索引碎片能增大索引樹的大小,增加不必要的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語句還是有得商量的地方。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 焦作市| 湾仔区| 凌源市| 郎溪县| 健康| 体育| 友谊县| 东莞市| 娄底市| 安岳县| 泰兴市| 江门市| 乐东| 东方市| 平果县| 淮北市| 崇义县| 乌苏市| 丽水市| 鹿泉市| 宿迁市| 阳山县| 富平县| 正宁县| 海城市| 泌阳县| 灵川县| 贞丰县| 麦盖提县| 凉城县| 黑河市| 兴海县| 甘谷县| 承德市| 三亚市| 和政县| 富蕴县| 内江市| 三原县| 峨眉山市| 达尔|