DBCC INDEXDEFRAG (Transact-SQL)

指定されたテーブルまたはビューのインデックスをデフラグします。

重要な注意事項重要

この機能は、Microsoft SQL Server の将来のバージョンで削除されます。新規の開発作業ではこの機能を使用しないようにし、現在この機能を使用しているアプリケーションはできるだけ早く修正してください。代わりに ALTER INDEX を使用してください。

トピック リンク アイコンTransact-SQL 構文表記規則

構文

DBCC INDEXDEFRAG
(
    { database_name | database_id | 0 } 
    , { table_name | table_id | view_name | view_id } 
    [ , { index_name | index_id } [ , { partition_number | 0 } ] ]
)
    [ WITH NO_INFOMSGS ] 

引数

  • database_name| database_id | 0
    デフラグするインデックスが含まれているデータベースを指定します。0 を指定すると、現在のデータベースが選択されます。データベース名は、識別子のルールに従っている必要があります。

  • table_name | table_id | view_name | view_id
    断片化を解消するインデックスが含まれているテーブルまたはビューを指定します。テーブル名とビュー名は、識別子の規則に従っている必要があります。

  • index_name |index_id
    断片化を解消するインデックスの ID または名前を指定します。インデックス ID を指定しないと、ステートメントは指定されたテーブルまたはビューのすべてのインデックスをデフラグします。インデックス名は、識別子の規則に従っている必要があります。

  • partition_number | 0
    デフラグするインデックスのパーティション番号です。パーティション番号を指定しない場合、またはパーティション番号に 0 を指定した場合、ステートメントは指定されたインデックス内のすべてのパーティションをデフラグします。

  • WITH NO_INFOMSGS
    重大度レベル 0 ~ 10 のすべての情報メッセージを表示しないようにします。

説明

DBCC INDEXDEFRAG は、リーフ ページの物理順序がリーフ ノードでの左から右への論理順序と一致するように、インデックスのリーフ レベルをデフラグするので、インデックスのスキャンのパフォーマンスが向上します。

注意

DBCC INDEXDEFRAG が実行されると、インデックスの断片化解消が直列に実行されます。つまり、単一のスレッドを使用して、単一のインデックスについて操作が実行されます。並列処理は実行されません。また、同じ DBCC INDEXDEFRAG ステートメントからの複数のインデックスについての操作は、1 つのインデックスについて同時に実行されます。

また、DBCC INDEXDEFRAG は、インデックス作成時に指定された FILL FACTOR を考慮しながら、インデックスのページの圧縮も行います。この圧縮によって作成された空のページは削除されます。詳細については、「FILL FACTOR」を参照してください。

インデックスが複数のファイルにわたる場合は、DBCC INDEXDEFRAG は一度に 1 つのファイルに対して断片化の解消を行います。ページがファイル間を移動することはありません。

DBCC INDEXDEFRAG は、5 分ごとに、完了した割合の予測値をレポートします。DBCC INDEXDEFRAG は、プロセスのどの時点でも停止することができ、停止時に完了していた作業は保持されます。

DBCC DBREINDEX (または一般のインデックス構築操作) とは異なり、DBCC INDEXDEFRAG はオンライン操作です。この操作では、長期間にわたってロックを保持することはありません。したがって、DBCC INDEXDEFRAG はクエリまたは更新の実行をブロックしません。デフラグの所要時間は断片化のレベルに関係するため、比較的断片化されていないインデックスのデフラグは、新しいインデックスの構築にかかる時間よりも短時間で済む場合があります。断片化がかなり進んでいるインデックスの場合、デフラグすると、再構築するよりも所用時間が著しく長くなる場合があります。

デフラグは、データベース復旧モデルの設定にかかわらず、常にすべてログに記録されます。詳細については、「ALTER DATABASE (Transact-SQL)」を参照してください。断片化がかなり進んだインデックスをデフラグした場合、インデックスの作成をすべてログに記録したときよりも多くのログが生成される可能性があります。ただし、ログのバックアップが頻繁に作成されているか、または復旧モデルに SIMPLE が設定されている場合、断片化の解消は一連の短いトランザクションとして実行されるため大量のログは必要なくなります。

制限事項

DBCC INDEXDEFRAG は、インデックス リーフ ページの再編成を行います。したがって、特定のインデックスがディスク上の他のインデックスと交互に配置されている場合は、そのインデックスに対して DBCC INDEXDEFRAG を実行すると、隣接するインデックス内では一部のリーフ ページが作成されません。ページが連続して配置されるようにするには、インデックスを再構築します。

DBCC INDEXDEFRAG を使用して次のインデックスの断片化を解消することはできません。

  • 無効化されたインデックス。

  • ページ ロックが OFF に設定されたインデックス。

  • 空間インデックスです。

DBCC INDEXDEFRAG は、システム テーブルに対して使用できません。

結果セット

DBCC INDEXDEFRAG は、(WITH NO_INFOMSGS が指定されている場合を除き) インデックスがステートメント内で指定されている場合に、次の結果セットを返します (値は異なることがあります)。

Pages Scanned Pages Moved Pages Removed
------------- ----------- -------------
359           346         8

(1 row(s) affected)

DBCC execution completed. If DBCC printed error messages, contact your system administrator.

権限

呼び出し元はテーブルを所有しているか、固定サーバー ロール sysadmin、固定データベース ロール db_owner、または固定データベース ロール db_ddladmin のメンバーである必要があります。

A. DBCC INDEXDEFRAG を使用してインデックスの断片化を解消する

次の例では、AdventureWorks2008R2 データベースの Production.Product テーブルにある PK_Product_ProductID インデックスのすべてのパーティションをデフラグします。

DBCC INDEXDEFRAG (AdventureWorks2008R2, "Production.Product", PK_Product_ProductID)
GO

B. DBCC SHOWCONTIG と DBCC INDEXDEFRAG を使用してデータベース内のインデックスの断片化を解消する

次の例では、宣言されたしきい値を超えて断片化しているデータベースのインデックスすべての断片化を解消する、簡単な方法を示しています。

/*Perform a 'USE <database name>' to select the database in which to run the script.*/
-- Declare variables
SET NOCOUNT ON;
DECLARE @tablename varchar(255);
DECLARE @execstr   varchar(400);
DECLARE @objectid  int;
DECLARE @indexid   int;
DECLARE @frag      decimal;
DECLARE @maxfrag   decimal;

-- Decide on the maximum fragmentation to allow for.
SELECT @maxfrag = 30.0;

-- Declare a cursor.
DECLARE tables CURSOR FOR
   SELECT TABLE_SCHEMA + '.' + TABLE_NAME
   FROM INFORMATION_SCHEMA.TABLES
   WHERE TABLE_TYPE = 'BASE TABLE';

-- Create the table.
CREATE TABLE #fraglist (
   ObjectName char(255),
   ObjectId int,
   IndexName char(255),
   IndexId int,
   Lvl int,
   CountPages int,
   CountRows int,
   MinRecSize int,
   MaxRecSize int,
   AvgRecSize int,
   ForRecCount int,
   Extents int,
   ExtentSwitches int,
   AvgFreeBytes int,
   AvgPageDensity int,
   ScanDensity decimal,
   BestCount int,
   ActualCount int,
   LogicalFrag decimal,
   ExtentFrag decimal);

-- Open the cursor.
OPEN tables;

-- Loop through all the tables in the database.
FETCH NEXT
   FROM tables
   INTO @tablename;

WHILE @@FETCH_STATUS = 0
BEGIN
-- Do the showcontig of all indexes of the table
   INSERT INTO #fraglist 
   EXEC ('DBCC SHOWCONTIG (''' + @tablename + ''') 
      WITH FAST, TABLERESULTS, ALL_INDEXES, NO_INFOMSGS');
   FETCH NEXT
      FROM tables
      INTO @tablename;
END;

-- Close and deallocate the cursor.
CLOSE tables;
DEALLOCATE tables;

-- Declare the cursor for the list of indexes to be defragged.
DECLARE indexes CURSOR FOR
   SELECT ObjectName, ObjectId, IndexId, LogicalFrag
   FROM #fraglist
   WHERE LogicalFrag >= @maxfrag
      AND INDEXPROPERTY (ObjectId, IndexName, 'IndexDepth') > 0;

-- Open the cursor.
OPEN indexes;

-- Loop through the indexes.
FETCH NEXT
   FROM indexes
   INTO @tablename, @objectid, @indexid, @frag;

WHILE @@FETCH_STATUS = 0
BEGIN
   PRINT 'Executing DBCC INDEXDEFRAG (0, ' + RTRIM(@tablename) + ',
      ' + RTRIM(@indexid) + ') - fragmentation currently '
       + RTRIM(CONVERT(varchar(15),@frag)) + '%';
   SELECT @execstr = 'DBCC INDEXDEFRAG (0, ' + RTRIM(@objectid) + ',
       ' + RTRIM(@indexid) + ')';
   EXEC (@execstr);

   FETCH NEXT
      FROM indexes
      INTO @tablename, @objectid, @indexid, @frag;
END;

-- Close and deallocate the cursor.
CLOSE indexes;
DEALLOCATE indexes;

-- Delete the temporary table.
DROP TABLE #fraglist;
GO