このT-SQLを実行してすべてのテーブルを一度に最適化しようとしたデータベースがあります。
SELECT
'ALTER INDEX all ON ' + name + ' REORGANIZE;' + CHAR(10) +
'ALTER INDEX all ON ' + name + ' REBUILD;'
FROM sys.tables
次に、出力をコピーして新しいクエリウィンドウに貼り付け、実行します。エラーは発生しませんでしたが、まだ断片化しています。私も両方のコマンドを別々に実行してみましたが、それでも断片化があります。 注: AaronによってREORGANIZE
は不要であることを認識しており、動的SQLを使用してこれを自動化できることを認識しています。
私はこれを実行して、まだ断片化があることを確認しました:
SELECT * FROM
sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, NULL)
WHERE avg_fragmentation_in_percent > 0
そして私は得ました:
database_id object_id index_id partition_number index_type_desc alloc_unit_type_desc index_depth index_level avg_fragmentation_in_percent fragment_count avg_fragment_size_in_pages page_count avg_page_space_used_in_percent record_count ghost_record_count version_ghost_record_count min_record_size_in_bytes max_record_size_in_bytes avg_record_size_in_bytes forwarded_record_count compressed_page_count
85 171147655 1 1 CLUSTERED INDEX IN_ROW_DATA 2 0 36.3636363636364 5 2.2 11 NULL NULL NULL NULL NULL NULL NULL NULL NULL
85 421576540 1 1 CLUSTERED INDEX IN_ROW_DATA 2 0 75 7 1.14285714285714 8 NULL NULL NULL NULL NULL NULL NULL NULL NULL
85 965578478 1 1 CLUSTERED INDEX IN_ROW_DATA 2 0 14.7058823529412 6 5.66666666666667 34 NULL NULL NULL NULL NULL NULL NULL NULL NULL
85 1061578820 1 1 CLUSTERED INDEX IN_ROW_DATA 2 0 40 4 1.25 5 NULL NULL NULL NULL NULL NULL NULL NULL NULL
85 1109578991 1 1 CLUSTERED INDEX IN_ROW_DATA 2 0 30.7692307692308 5 2.6 13 NULL NULL NULL NULL NULL NULL NULL NULL NULL
85 1205579333 2 1 NONCLUSTERED INDEX IN_ROW_DATA 2 0 50 5 1.6 8 NULL NULL NULL NULL NULL NULL NULL NULL NULL
85 1493580359 1 1 CLUSTERED INDEX IN_ROW_DATA 2 0 50 6 1.66666666666667 10 NULL NULL NULL NULL NULL NULL NULL NULL NULL
本当に基本的なものが欠けているのはわかっていますが、何が原因なのかわかりません。
テーブルは小さいです。テーブルのページ数は次のとおりです。
11、8、6、5、13、8、10
合計で480kbを占めています。文字通りデフラグするものはまったくありません。
編集:これはもう少し説明する必要があります。
新しいテーブルまたはインデックスは、通常、均一なエクステントではなく、混合から最初の8ページに割り当てられます。したがって、最初の8ページのそれぞれを異なる混合エクステントから割り当てることができます。したがって、8ページを消費するテーブルまたはインデックスは、8つの異なる混合エクステントのそれぞれに1つずつ、8つのフラグメントを持つことができます。
より広く使用されているデフラグスクリプト(以下にリンクされているいくつかの例)は、このため小さなテーブルを除外する傾向があります。 IIRC、500ページ未満が片方または両方にあります。これらのサイズでは、デフラグによるメリットはほとんどなく、断片化の数値は、混合エクステント割り当てによって歪められる可能性があります。
" Microsoft SQL Server 2000インデックスデフラグのベストプラクティス "からの引用:
「フラグメンテーションはディスクI/Oに影響します。したがって、SQL Serverによってページがキャッシュされる可能性が低いため、大きなインデックスに焦点を合わせてください。DBCCSHOWCONTIGによって報告されたページ数を使用して、インデックスのサイズ(各ページはサイズは8 KBです。一般に、1,000ページ未満のインデックスの断片化レベルを気にする必要はありません。テストでは、10,000ページを超えるインデックスでパフォーマンスが向上し、最大の大幅に多くのページ(50,000ページを超える)。
したがって、この種の質問はあなたの質問に答え、マークとアーロンの答えを裏付けます。
インデックスの断片化に関する適切な情報は、Brent Ozarの次の記事にあります。
また、一般的な(断片化の問題についても)インデックスに関するすばらしい情報の海は Kimberly Trippのブログ で見つけることができます。
これは質問への回答を意図したものではありませんが、コメントに収まることはありません。出力をコピーして別のウィンドウに貼り付けることなく、このスクリプトを動的に構築できます。 REORGANIZE
、次にREBUILD
を使用する理由はまったくないことを考慮に入れてください。
DECLARE @sql NVARCHAR(MAX) = N'';
SELECT @sql += N'ALTER INDEX all ON ' + name + ' REBUILD;
' FROM sys.tables;
PRINT @sql; -- to see the first 8,000 characters and make sure it checks out
-- EXEC sp_executesql @sql;