任何人都可以在'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. NHibernate.Search索引重建
- 4. zend_search_lucene重建索引
- 5. 重新索引多索引问题
- 6. 可以重新运行的TSQL脚本索引创建
- 7. SQL删除和创建不重建脚本索引?
- 8. elasticsearch重新索引错误 - 重新索引从远程
- 9. 重新索引/刷新SectionIndexer
- 10. 重新构建索引的SQL查询
- 11. 拆分Lucene索引文件而不重新索引
- 12. 在ElasticSearch中重新索引索引以更改分片数量
- 13. jQuery脚本,索引和重新显示图像
- 14. 重组/重建单索引与所有表索引
- 15. 段索引与搜索栏重叠(swift)
- 16. 重新索引表;从
- 17. PHP重新索引数组?
- 18. 重新索引SOLR文档
- 19. Magento:“不能重新索引。”
- 20. Solr重新索引行为
- 21. 重新设计MySQL索引
- 22. 如何使用核心重新加载来重建索引索引
- 23. Lucene创建重复索引
- 24. 手动重建pycharm索引
- 25. Nexus3重建索引错误
- 26. 重建SQL索引 - 何时?
- 27. 重建索引oracle 10G
- 28. 在SQL Server 2008上重新组织和重建索引
- 29. Git索引重置本身
- 30. UITableView部分索引重叠搜索栏
为什么不呢?任何人都可以选择提出他们问维基问题的任何问题。它避免了丢失重要点。 – 2009-07-06 13:09:46