任何人都可以在'avg_fragmentation_in_percent'超過特定限制時更好地重建和重新索引碎片索引(如果不使用遊標,這個腳本會更好嗎?)?重建和重新索引分段索引的腳本?
12
A
回答
18
要重建使用:
ALTER INDEX __NAME_OF_INDEX__ ON __NAME_OF_TABLE__ REBUILD
或重組用途:
ALTER INDEX __NAME_OF_INDEX__ ON __NAME_OF_TABLE__ REORGANIZE
改組應在較低(< 30%)分片使用,但僅重建(這是較重到數據庫)將碎片率降至0%。
有關更多信息,請參閱https://msdn.microsoft.com/en-us/library/ms189858.aspx
4
我發現以下腳本非常適合維護索引,您可以將此計劃安排在每晚運行或您希望的其他任何時間範圍內運行。
6
下面是修改腳本,我從http://www.foliotek.com/devblog/sql-server-optimization-with-index-rebuilding,我發現在這裏發表了有益的。 雖然它使用遊標,我知道遊標的主要問題是什麼,它可以很容易地轉換爲無遊標的版本。
它有很好的文檔記錄,您可以通過它輕鬆閱讀並修改您的需求。
IF OBJECT_ID('tempdb..#work_to_do') IS NOT NULL
DROP TABLE tempdb..#work_to_do
BEGIN TRY
--BEGIN TRAN
use yourdbname
-- Ensure a USE statement has been executed first.
SET NOCOUNT ON;
DECLARE @objectid INT;
DECLARE @indexid INT;
DECLARE @partitioncount BIGINT;
DECLARE @schemaname NVARCHAR(130);
DECLARE @objectname NVARCHAR(130);
DECLARE @indexname NVARCHAR(130);
DECLARE @partitionnum BIGINT;
DECLARE @partitions BIGINT;
DECLARE @frag FLOAT;
DECLARE @pagecount INT;
DECLARE @command NVARCHAR(4000);
DECLARE @page_count_minimum SMALLINT
SET @page_count_minimum = 50
DECLARE @fragmentation_minimum FLOAT
SET @fragmentation_minimum = 30.0
-- Conditionally select tables and indexes from the sys.dm_db_index_physical_stats function
-- and convert 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 ,
page_count AS page_count
INTO #work_to_do
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL,
'LIMITED')
WHERE avg_fragmentation_in_percent > @fragmentation_minimum
AND index_id > 0
AND page_count > @page_count_minimum;
IF CURSOR_STATUS('global', 'partitions') >= -1
BEGIN
PRINT 'partitions CURSOR DELETED' ;
CLOSE partitions
DEALLOCATE partitions
END
-- Declare the cursor for the list of partitions to be processed.
DECLARE partitions CURSOR LOCAL
FOR
SELECT *
FROM #work_to_do;
-- Open the cursor.
OPEN partitions;
-- Loop through the partitions.
WHILE (1 = 1)
BEGIN;
FETCH NEXT
FROM partitions
INTO @objectid, @indexid, @partitionnum, @frag, @pagecount;
IF @@FETCH_STATUS < 0
BREAK;
SELECT @objectname = QUOTENAME(o.name) ,
@schemaname = QUOTENAME(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 = QUOTENAME(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;
SET @command = N'ALTER INDEX ' + @indexname + N' ON '
+ @schemaname + N'.' + @objectname + N' REBUILD';
IF @partitioncount > 1
SET @command = @command + N' PARTITION='
+ CAST(@partitionnum AS NVARCHAR(10));
EXEC (@command);
--print (@command); //uncomment for testing
PRINT N'Rebuilding index ' + @indexname + ' on table '
+ @objectname;
PRINT N' Fragmentation: ' + CAST(@frag AS VARCHAR(15));
PRINT N' Page Count: ' + CAST(@pagecount AS VARCHAR(15));
PRINT N' ';
END;
-- Close and deallocate the cursor.
CLOSE partitions;
DEALLOCATE partitions;
-- Drop the temporary table.
DROP TABLE #work_to_do;
--COMMIT TRAN
END TRY
BEGIN CATCH
--ROLLBACK TRAN
PRINT 'ERROR ENCOUNTERED:' + ERROR_MESSAGE()
END CATCH
5
兩個解決方案:一個簡單的和一個更加先進。
介紹
有提供給您兩種解決方案取決於您的問題的嚴重性
替換爲自己的值,如下所示:
- 替換
XXXMYINDEXXXX
用的名字索引。 - 用表名稱替換
XXXMYTABLEXXX
。 - 用數據庫的名稱替換
XXXDATABASENAMEXXX
。
溶液1索引
重建爲一個表中所有索引在離線模式下
ALTER INDEX ALL ON XXXMYTABLEXXX REBUILD
在離線模式下重建一個指定的索引爲表
ALTER INDEX XXXMYINDEXXXX ON XXXMYTABLEXXX REBUILD
解決方案2.碎片化
碎片是表格中的問題,表格中經常會添加和刪除條目。
檢查碎片百分比
SELECT
ips.[index_id] ,
idx.[name] ,
ips.[avg_fragmentation_in_percent]
FROM
sys.dm_db_index_physical_stats(DB_ID(N'XXXMYDATABASEXXX'), OBJECT_ID(N'XXXMYTABLEXXX'), NULL, NULL, NULL) AS [ips]
INNER JOIN sys.indexes AS [idx] ON [ips].[object_id] = [idx].[object_id] AND [ips].[index_id] = [idx].[index_id]
碎片5..30%
如果碎片值大於5%但低於30%,那麼就值得重新組織索引。
重新組織的所有索引爲表
ALTER INDEX ALL ON XXXMYTABLEXXX REORGANIZE
重新組織一項所述的表
ALTER INDEX XXXMYINDEXXXX ON XXXMYTABLEXXX REORGANIZE
碎片30%+
如果碎片值爲30%指定索引或更高,那麼值得重建,然後在線模式索引。
重建在聯機模式下的所有索引的表
ALTER INDEX ALL ON XXXMYTABLEXXX REBUILD WITH (ONLINE = ON)
重建一個指定的索引在聯機模式下爲表
ALTER INDEX XXXMYINDEXXXX ON XXXMYTABLEXXX REBUILD WITH (ONLINE = ON)
2
真正的答案,在2016年和2017年,是:使用Ola Hallengren的劇本:
https://ola.hallengren.com/sql-server-index-and-statistics-maintenance.html
這就是我們所有人都需要知道或打擾,在這一點上我們的相互進化。
相關問題
- 1. Lotus腳本重建索引
- 2. 重建索引
- 3. VFP。重新創建索引
- 4. Elasticsearch重新索引
- 5. 重新索引重複行
- 6. zend_search_lucene重建索引
- 7. NHibernate.Search索引重建
- 8. 刪除lucene索引並重新索引
- 9. 重新索引多索引問題
- 10. 可以重新運行的TSQL腳本索引創建
- 11. SQL刪除和創建不重建腳本索引?
- 12. 自動重組和重建索引
- 13. elasticsearch重新索引錯誤 - 重新索引從遠程
- 14. 重新索引/刷新SectionIndexer
- 15. 重建索引是否等同於刪除並重新創建索引?
- 16. 重新構建索引的SQL查詢
- 17. 在ElasticSearch中重新索引索引以更改分片數量
- 18. 拆分Lucene索引文件而不重新索引
- 19. SQL索引重建:索引碎片百分比增加?
- 20. jQuery腳本,索引和重新顯示圖像
- 21. 重新索引或重新排序組
- 22. 重組/重建單索引與所有表索引
- 23. 段索引與搜索欄重疊(swift)
- 24. 重建Lucene的搜索索引失敗
- 25. 重新索引數據框的問題:重建索引只對唯一有價值的索引對象有效
- 26. 重新構建SQL Server全文索引
- 27. PHP重新索引數組?
- 28. Magento:「不能重新索引。」
- 29. Solr重新索引行爲
- 30. 重新索引SOLR文檔
爲什麼不呢?任何人都可以選擇提出他們問維基問題的任何問題。它避免了丟失重要點。 – 2009-07-06 13:09:46