是否有可能增加一个维护作业检查索引的碎片。 如果大于50%,则自动重建这些索引?
索引大小可以变化从100MB到10GB。 SQL 2005。
谢谢。
是否有可能增加一个维护作业检查索引的碎片。 如果大于50%,则自动重建这些索引?
索引大小可以变化从100MB到10GB。 SQL 2005。
谢谢。
我使用这个脚本。 请注意,我劝你读了有关我在这里使用他们在SQL2005 +一个隐藏的宝石的DMV。
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
CREATE TABLE #FragmentedIndexes
(
DatabaseName SYSNAME
, SchemaName SYSNAME
, TableName SYSNAME
, IndexName SYSNAME
, [Fragmentation%] FLOAT
)
INSERT INTO #FragmentedIndexes
SELECT
DB_NAME(DB_ID()) AS DatabaseName
, ss.name AS SchemaName
, OBJECT_NAME (s.object_id) AS TableName
, i.name AS IndexName
, s.avg_fragmentation_in_percent AS [Fragmentation%]
FROM sys.dm_db_index_physical_stats(db_id(),NULL, NULL, NULL, 'SAMPLED') s
INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id]
AND s.index_id = i.index_id
INNER JOIN sys.objects o ON s.object_id = o.object_id
INNER JOIN sys.schemas ss ON ss.[schema_id] = o.[schema_id]
WHERE s.database_id = DB_ID()
AND i.index_id != 0
AND s.record_count > 0
AND o.is_ms_shipped = 0
DECLARE @RebuildIndexesSQL NVARCHAR(MAX)
SET @RebuildIndexesSQL = ''
SELECT
@RebuildIndexesSQL = @RebuildIndexesSQL +
CASE
WHEN [Fragmentation%] > 30
THEN CHAR(10) + 'ALTER INDEX ' + QUOTENAME(IndexName) + ' ON '
+ QUOTENAME(SchemaName) + '.'
+ QUOTENAME(TableName) + ' REBUILD;'
WHEN [Fragmentation%] > 10
THEN CHAR(10) + 'ALTER INDEX ' + QUOTENAME(IndexName) + ' ON '
+ QUOTENAME(SchemaName) + '.'
+ QUOTENAME(TableName) + ' REORGANIZE;'
END
FROM #FragmentedIndexes
WHERE [Fragmentation%] > 10
DECLARE @StartOffset INT
DECLARE @Length INT
SET @StartOffset = 0
SET @Length = 4000
WHILE (@StartOffset < LEN(@RebuildIndexesSQL))
BEGIN
PRINT SUBSTRING(@RebuildIndexesSQL, @StartOffset, @Length)
SET @StartOffset = @StartOffset + @Length
END
PRINT SUBSTRING(@RebuildIndexesSQL, @StartOffset, @Length)
EXECUTE sp_executesql @RebuildIndexesSQL
DROP TABLE #FragmentedIndexes
也请记住,此脚本可以运行一段时间,并阻止访问你的表。 除非你有Enterprise版本重建索引时,SQL可以锁定表。 直到指数defrag完成使用索引这将阻止所有查询到该表。 因此,不建议仅运行期间的维护窗口期间运行时间索引重建。 如果您正在运行企业版,您可以在线使用ONLINE = ON选项碎片整理的索引。 这将使用更多的空间,但你的表不会被阻塞/磁盘碎片整理操作过程中锁定。
如果您需要了解更多信息呐喊。
更新:
如果你是一个较小的数据库上运行这个查询,你也许可以使用“详细”参数调用sys.dm_db_index_physical_stats。 这可能是指数的更详细的检查。 在评论的讨论也指出,在更大的表,那么很可能是值得做采样扫描,因为这将有助于减少做索引扫描所需要的时间。
在情况下,你想避免创建任何临时表和解析字符串,创建SQL字符串列表中。 下面是完成它的有效方法:
USE databasename
GO
DECLARE @Queryresult NVARCHAR(4000)
SET @Queryresult=''
SELECT
@Queryresult=@Queryresult + 'ALTER INDEX ' + QUOTENAME(i.name) + ' ON '
+ QUOTENAME('dbo') + '.'
+ QUOTENAME(OBJECT_NAME(i.OBJECT_ID)) + ' REBUILD;'
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'SAMPLED') ss
INNER JOIN sys.indexes i ON i.OBJECT_ID = ss.OBJECT_ID AND i.index_id = ss.index_id
INNER JOIN sys.objects o ON ss.object_id = o.object_id
WHERE ss.avg_fragmentation_in_percent > 50
AND ss.record_count > 0
AND o.is_ms_shipped = 0 --Excludes any objects created as a part of SQL Server installation
AND ss.index_id > 0 --Excludes heap indexes
EXEC sp_executesql @Queryresult
是的你可以。
您可以使用此查询得到碎片索引:
SELECT OBJECT_NAME(i.OBJECT_ID) AS TableName,
i.name AS IndexName,
indexstats.avg_fragmentation_in_percent
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'DETAILED') indexstats
INNER JOIN sys.indexes i ON i.OBJECT_ID = indexstats.OBJECT_ID
AND i.index_id = indexstats.index_id
WHERE indexstats.avg_fragmentation_in_percent > 20
并根据其结果只是建立一个命令来重新创建它们
我想在存储过程包一切,从SQL Server作业调用它
仅供参考,50%是一个非常大的碎片。 我会去的少。
您可以使用sys.dm_db_index_physical_stats来获得有关索引碎片(见avg_fragmentation_in_percent列)的信息。 然后,你可以做,只要达到你的门槛重建子句的ALTER指数。