sql >> データベース >  >> RDS >> Sqlserver

断片化の結果に基づいて INDEX の再構築を自動化しますか?

    私はこのスクリプトを使用します。ここで使用している dmv について読むことをお勧めします。それらは SQL2005+ の隠された宝石です。

    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 はインデックスを再構築するときにテーブルをロックできます。これにより、インデックスのデフラグが完了するまで、インデックスを使用してそのテーブルへのすべてのクエリがブロックされます。したがって、運用時間中にインデックスの再構築を実行するのは、メンテナンス期間中のみにすることはお勧めしません。 Enterprise Edition を実行している場合は、ONLINE=ON オプションを使用してインデックスをオンラインで最適化できます。これにより、より多くのスペースが使用されますが、最適化操作中にテーブルがブロック/ロックされることはありません。

    さらに情報が必要な場合は声をかけてください。

    更新:

    小規模なデータベースでこのクエリを実行している場合は、おそらく sys.dm_db_index_physical_stats への呼び出しで「DETAILED」パラメーターを使用できます。これはおそらく、インデックスのより詳細な調査です。コメント内の議論では、インデックス スキャンに必要な時間を短縮するのに役立つため、はるかに大きなテーブルではおそらく SAMPLED スキャンを実行する価値があることも指摘されています。



    1. ネストされたmysqlクエリをcodeigniterスタイルに変換します

    2. /192.168.15.186(ポート80)への接続に失敗した解決方法:接続に失敗しました:WindowsファイアウォールのETIMEDOUT(接続がタイムアウトしました)

    3. PHPおよびMYSQLを使用して、mysqlデータベースのジャンク文字をアラビア文字と照合する方法

    4. 大きなinnodbテーブルを高速コピーする方法