【问题标题】:SQL Server rebuilding indexes - scriptSQL Server 重建索引 - 脚本
【发布时间】:2019-01-22 00:40:30
【问题描述】:

我正在使用来自@Namphibian 的脚本,但我有一些问题。

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

但我使用的是“DETAILED”而不是“SAMPLED”,但仍有一些索引没有重建。我发现一些索引具有相同的超过 30% 的碎片值,但仍未重建或重组。该脚本在过去 4 天的每晚都运行。我的问题是我不能为这项任务使用维护计划。

有什么想法吗?

【问题讨论】:

  • 应该是表太小了,查看s.page_count的索引
  • 您是否尝试手动重建其中一个索引?这会导致与脚本不同的结果吗?
  • 与其重新发明轮子,不如看看Ola Hallengren's Maintenance Solution。这在 SQL Server 社区中被高度重视并广泛用于数据库维护。
  • 现在我正在查看未重建索引的数量,大约有一百个。我知道这是一个包含大量索引的庞大数据库。 @ Tyron78我会尝试重建一些这是个好主意谢谢,明天我会在这里发布结果。 @DanGuzman 谢谢丹,但这对我来说太复杂了我不太擅长阅读脚本来在那里找到一些东西,因为我说这对我来说太复杂了:(我只需要一些简单的东西来从一个特定的数据库中获取我的索引和确定哪一个超过 30%,然后重建它们。
  • @RomaneS 你还有这个问题吗?当您像 tyron78 所说的那样手动重建这些索引时发生了什么?

标签: sql sql-server indexing rebuild fragmentation


【解决方案1】:

根据这个答案: https://dba.stackexchange.com/questions/18372/why-index-rebuild-does-not-reduce-index-fragmentatation

您需要考虑索引的页数才能知道是否进行重建

我会建议将您的 INSERT INTO SELECT 更改为此

    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%],
    page_count
FROM 
    sys.dm_db_index_physical_stats(db_id(),NULL, NULL, NULL, 'DETAILED') 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
    AND s.avg_fragmentation_in_percent > 0
    AND page_count > 1000

【讨论】:

  • 嗨@polzka90,当我尝试更改该行时,它最终会出现此错误:Msg 213,Level 16,State 1,Line 11 列名或提供的值的数量与表定义不匹配。任何建议我做错了什么? :(
  • 抱歉耽搁了,你能放一些链接来查看所有新查询吗,我测试了一下,它可以工作
猜你喜欢
  • 2011-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-04
  • 1970-01-01
相关资源
最近更新 更多