この記事は、 sp_spaceusedの出力を分析するための取り組みです。 ストアドプロシージャ。
はじめに
データベースの内部使用状況と成長傾向を理解することは、データベースの適切なサイズを定義する上で重要な役割を果たします。 sp_spaceusedは、データベースで使用されているディスク領域を見つけるために、おそらく管理者が最も広く実行しているシステムストアドプロシージャです。これにより、データベースの使用状況を簡単に把握できます。統計学。 sp_spaceusedは、行数、データサイズ、インデックスサイズ、使用済みスペースの量、各オブジェクトによる未使用スペース、およびデータベースの未割り当てサイズを表示するために使用されます。 sp_spaceusedによって指定された値を見ても、データベース、データファイル、またはログファイルを縮小することを考えるべきではありません。多くの場合、私たちは自分たちが何をしているのか気づいていません。多くの場合、このようなリソース固有の操作を行った後遺症がどうなるかはわかりません。 sp_spaceusedの出力は、データベースの現在のパフォーマンスについて多くのことを教えてくれます。 未割り当て 列と未使用 列には、データベースレベルとテーブルレベルに残っている空き容量が表示されます。
この記事では次のことを考慮しています:
- sp_spaceusedの概要
- 未割り当ておよび未使用の列に対する自動拡張設定の影響
- データベースおよびインスタンスレベルでのスペース使用量の詳細の検索
- 自動成長イベントの測定
- mdfおよびldfファイルサイズの検索
- データベースのパフォーマンスを決定する要因
- その他…
sp_spaceusedの内部
すべてのテーブルのスペース使用量の詳細をキャプチャする
以下のT-SQLでは、ドキュメント化されていないストアドプロシージャsp_MSforeachtableを使用して、現在のデータベースコンテキストのスコープ内のすべてのテーブルをトラバースし、コンテキスト内のすべてのテーブルのスペース使用量メトリックを取得します。
Declare @tbl_sp_spaceused table( name varchar(100) NULL, rows bigint NULL, reserved varchar(20) NULL, data varchar(20) NULL, index_size varchar(20) NULL, unused varchar(20) NULL ) -- insert output of sp_spaceused to table variable INSERT INTO @tbl_sp_spaceused ( name, rows, reserved, data, index_size, unused ) EXEC sp_MSforeachtable @command1 = 'EXEC sp_spaceused [?]' SELECT * FROM @tbl_sp_spaceused order by rows desc
すべてのデータベースのスペース使用量の詳細をキャプチャします
文書化されていないストアドプロシージャsp_MSforeachDBは、現在のSQLインスタンスのスコープ内でデータベース全体をトラバースして、すべてのデータベースのスペース使用量情報を取得するために使用されます。
declare @tbl_sp_spaceusedDBs table( database_name varchar(100) NOT NULL, database_size varchar(50) NULL, unallocated varchar(30) NULL, reserved varchar(20) NULL, data varchar(20) NULL, index_size varchar(20) NULL, unused varchar(20) NULL ) INSERT INTO @tbl_sp_spaceusedDBs ( database_name, database_size, unallocated, reserved, data, index_size, unused ) EXEC sp_msforeachdb @command1="use ? exec sp_spaceused @oneresultset = 1" SELECT * FROM @tbl_sp_spaceusedDBs ORDER BY database_name, database_size
ここでは、 database_name データベースの名前です。この場合、 PythonSample 。 database_size U nallocated + Reserved + Data + Index + Unused =MDF + LDF (=この場合は848 MB)。 未割り当て ここのスペースは51.94MBです。
これは、実際には、データベース用にマークされたディスク境界です。 sp_spaceusedは、データベースレベルで定義された未割り当ての列を出力します。この列はどのテーブルにも予約されておらず、拡張の余地があると主張する最初のオブジェクトによって取得される可能性があります。
未割り当て spaceはデータファイル内の空き領域であるため、クエリを発行するたびに自動拡張する必要はありません。通常、SQL Serverストレージエンジンは、比例塗りつぶしアルゴリズムと呼ばれるメカニズムを使用して自動拡張を管理します。エクステントの管理は、ファイルで発生した書き込みの数に基づいて効果的に行われます。同時に、使用済みスペースがしきい値に達すると、イベントがトリガーされてさらに自動拡張されます。未割り当て領域の適切な値の設定は、ニーズと状況、およびデータベースの使用の性質によって異なります。未割り当てスペースとは、まだ使用されていないスペースであり、「手に入る」スペースです。本質的に、これらのエクステントはGAMページでビット1でマークされています。上からの自動成長の概念を理解すると、どのタイプの成長でも、さらに割り当てられていない範囲が生成される可能性があります。
次のSQLクエリを使用すると、自動拡張イベントが生成された回数と、データベースがプロセスのために保留にした時間の長さを確認できます。
DECLARE @fname NVARCHAR(1000); -- Get the name of the current default trace SELECT @fname = CAST(value AS VARCHAR(MAX)) FROM ::fn_trace_getinfo(DEFAULT) WHERE traceid = 1 AND property = 2; SELECT ft.StartTime [Start Time] ,t.name [Event Name] ,DB_NAME(ft.databaseid) [Database Name] ,ft.Filename [File Name] ,(ft.IntegerData*8)/1024.0 [Growth MB] ,(ft.duration/1000) [Duration MS] FROM ::fn_trace_gettable(@fname, DEFAULT) AS ft INNER JOIN sys.trace_events AS t ON ft.EventClass = t.trace_event_id WHERE (ft.EventClass = 92 -- DateFile Auto-growth OR ft.EventClass = 93) -- LogFile Auto-growth ORDER BY ft.StartTime
それぞれの用語の意味を見てみましょう:
予約済み :データベースオブジェクトで使用するために予約されているスペース=(データ+インデックス+未使用 )=476704 + 1280 + 1312=479296KB。これは、オブジェクトがどれだけいっぱいかを示します。理想的には、トランザクションテーブルには未使用スペースの10%が予想されます。
データ :データの実際のサイズ。これは、データベースのすべてのデータファイルの合計です。
インデックス :インデックスによって使用されるスペースの量。
注:場合によっては、インデックスサイズのサイズが実際のデータのサイズよりも大きいことがわかりました。インデックスに関する限り、システムに必要なものは常にデータベースのパフォーマンスに依存します。多くの場合、読み取り操作は書き込み操作よりも重要です。また、他のいくつかのケースでは、読み取りよりも書き込みの方が重要です。読み取りが書き込みよりもはるかに重要であるとビジネスが判断した場合、そのシステムは、ビジネスとユーザーのパフォーマンス要件を満たすために大量のインデックスを必要とする可能性があります。
未使用 :まだ使用されていない予約済みスペースの一部
未使用は、割り当てられたエクステントのページですが、どのオブジェクトでもまだ使用されていません。エクステントが(均一または共有エクステントとして)割り当てられるとすぐに、そのエクステントで8つの予約済みページを取得します。使用されているページと使用されていないページがあります。
未使用 および未割り当て 出力の列が混乱する可能性があります。明確にするために、未使用 列の出力には、データベース全体に残っている空き領域の量は表示されません。代わりに、テーブル用に予約されているがデータで満たされていないスペースの合計量です。多くの場合、クラスター化インデックスを作成するか、既存のインデックスを管理することで、未使用のスペースを再利用できます。
sp_spaceusedの出力をさらに簡略化して、.mdfファイルと.logファイルのサイズを見つけることができます。予約済みスペースと未割り当てスペースの合計は、データ(またはMDF)ファイルのサイズとほぼ同じです。また、データベースサイズからMDFファイルサイズを差し引くと、ログファイルサイズが得られます。
したがって、ここに2つの式があります:
MDFファイルのサイズ=予約済み+未割り当て領域
ログファイルのサイズ=Database_Size–MDFファイルのサイズ
SELECT 476704+ 1280+ 1312 'Reserved KB', (479296/1024.00)+51.94 'MDFSizeMB', 848.00 - ((479296/1024.00)+51.94) 'LogSizeMB'
前述のポイントは、sp_spaceusedの出力の各列がどのように解釈、計算、分析されるかを示しています。
自動成長設定の影響
初期サイズと自動拡張構成は、未使用のスペースに大きな影響を与えます。これらに適切な値を設定することは困難です。自動成長がパーセンテージで成長するように設定されているケースをたくさん見ました。 100 GBのデータファイルサイズに対して自動拡張が25%に設定されていると仮定します。ディスクドライブをいっぱいにするのに必要な自動拡張イベントは4つだけです。
もう1つのケースは、インデックスの再構築です。この操作は、データが均一エクステントと混合エクステントの間で再シャッフルされるため、テーブルの未使用スペースに直接影響します。場合によっては、ページを再シャッフルしているときに、データファイルの自動拡張設定のために、操作によって未割り当て領域が発生することがあります。
自動拡張設定がデータベースに正しく設定されていないシナリオを考えてみましょう。これも問題です。データベースで自動拡張が有効になっている場合、データがすべてのスペースを使用していなくても、あるイベント中にドライブの拡張が自動的に行われることを意味します。
データファイルに適切な自動拡張設定を設定することは常に良い習慣です。データファイルの設定が正しくないと、物理的な断片化が発生し、システムのパフォーマンスが大幅に低下する場合があります。つまり、未割り当てのスペースがない場合、新しいデータは分散している可能性のある空の場所に配置しようとします。これはログファイルにも当てはまります。データベース内の未割り当て領域は、データファイルとログファイルの自動拡張設定に間接的に影響し、パフォーマンスに直接影響します。重要なのは、適切なバランスを見つけることです。
まとめ
- データベースの作成プロセスでは、定義されたサイズ(つまり、初期サイズ)は、データベースの実際のサイズに他なりません。この初期サイズはページヘッダーに記録されます。データベースの縮小プロセス中、プロセスは最小サイズを使用します 実際のデータサイズが最小サイズよりも小さい場合にのみ、プロパティを参照します。最小サイズはページヘッダーにもあり、DBCCPAGEコマンドを使用して確認できます。また、同じプロセスがDBCC SHRINKFILEにも当てはまります。これは、ファイルを初期サイズよりも小さく縮小します。
- データベースを縮小してドライブスペースを解放することはお勧めできませんが、決定はシナリオによって異なります。通常とは異なるシナリオでは、型破りなアクションが必要になる場合があります。ただし、データベースを縮小すると、データベースに断片化が生じることを覚えておく必要があります。 未割り当てのスペースの根本原因を分析することは常に良い習慣です。 および未使用スペース オブジェクトの。多くの場合、データの増加に対応するためにディスクを拡張することは、実行可能/推奨されるオプションです。
- 自動拡張の構成:SQL Serverが自動拡張操作を実行する場合、自動拡張イベントをトリガーしたトランザクションは、自動拡張イベントが完了するまで待機する必要があります。そうして初めて、トランザクション自体を完了することができます。
- 自動成長オプションは、パーセンテージではなく数値で設定することを常にお勧めします。
- テーブルに未使用のスペースが発生するのは、次の理由による可能性があります。
- フラグメンテーション
データの性質と定義のタイプが原因でデータがフラグメント化されると、未使用のスペースが生成されます。また、データを頻繁に変更する(すべてのUPDATE、INSERT、またはDELETE操作)と、ページ分割の数が増え、テーブルに未使用のスペースが生成される可能性が高くなります。 - テーブルにクラスター化されたインデックスがない
ヒープ内の断片化を減らすために、クラスター化されたインデックスを作成することを考えることができます。 テーブルの上。インデックスの断片化を減らすには、avg_fragmentation_in_percent値を決定してインデックスのメンテナンスを実行します。 - データのサイズ
場合によっては、適切なデータ型を使用するとデータ行が小さくなり、ページにより多くの行を配置できるようになります。内部の未使用スペースを減らすだけでなく、ページ分割の数を減らすことでパフォーマンスに影響を与えます。
- フラグメンテーション
- 未使用のスペースは、可変長列を削除した結果である可能性もあります。未使用のスペースをすぐに再利用するために、表または索引付きビューの可変長列に大幅な変更を加えた後、DBCCCLEANTABLEを使用してください。または、テーブルまたはビューのインデックスを再構築することもできます。ただし、これはより多くのリソースを消費する操作です。
- 比較的大きなデータ(> 8 KB)をロードすることになった場合、未使用のスペースは比較的大きくなります。このような場合、データページに大量の未使用スペースができてしまいます。
- SharePointの移行後、データベースに導入された未使用のスペースのかなりの量を確認できます。再利用はより遅いプロセスであり、ゴーストクリーンアッププロセスはこれらのページを削除し、解放は一定期間にわたって行われます。
- 場合によっては、sp_spaceusedの値が正しくない可能性があります。 sp_spaceusedは、すべての見積もりを保持するシステムオブジェクトから情報を取得しますが、不正確な場合があります。この理由の1つは、データベースの移行中、統計が古くなっている場合、システムでDDLが頻繁に変更されている場合、または大量の一括コピー操作を実行した後です。システム・オブジェクトを同期するには、DBCC updateusage(0)またはDBCC CHECKTABLEステートメントを使用して、sp_spaceusedが最新の正確なデータを返すようにします。ただし、DBCCコマンドはリソースを大量に消費することに注意してください。その使用法の意味をよく理解している。 DBCC updateusageコマンドを実行すると、SQL Serverデータベースエンジンはデータベース内のデータページをスキャンし、 sys.allocation_unitsに必要な修正を加えます。 およびsys.partitions 各テーブルで使用されるストレージスペースに関するカタログビュー。
参照
- https://msdn.microsoft.com/en-us/library/cc280360.aspx
- https://docs.microsoft.com/en-us/sql/t-sql/database-console-commands/dbcc-cleantable-transact-sql
- https://docs.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-database-files-transact-sql