サイズの見積もりで、インデックスが使用するスペースの量を考慮に入れましたか?また、(N[VAR]CHAR
ではなく[VAR]CHAR
)マルチバイトとして設定されたテキストフィールドがあり、入力ファイルがUTF-8または1文字あたり1バイトのプレーンの場合、ストレージ要件は最大2倍になります。さらに、テーブルにクラスター化されたキー/インデックスがある場合、このサイズはすべての行のクラスター化されたキー値を含むため、テーブルのその他すべてのインデックスに影響することに注意してください(テーブルにNCHAR(10 )INTはどうしたらキーとそのあなたはまた、行あたり16のバイトを無駄にデータページ内の行あたりの余分な16バイトを使用しているだけでなく、あなたのクラスタ化キー/インデックスでそのテーブルの上に他のすべてのインデックス)。
また、一部のスペースは割り当てられますが、未使用です。DBエンジンが削除後に割り当てられたスペースを残して、そのテーブルの新しいデータにすぐに再び使用できるようにするため、または挿入と削除のパターンが多くのページだけを残したためですいっぱい。
以下を実行できます。
SELECT o.name
, SUM(ps.reserved_page_count)/128.0 AS ReservedMB
, SUM(ps.used_page_count)/128.0 AS UsedMB
, SUM(ps.reserved_page_count-ps.used_page_count)/128.0 AS DiffMB
FROM sys.objects o
JOIN sys.dm_db_partition_stats ps ON o.object_id = ps.object_id
WHERE OBJECTPROPERTYEX(o.object_id, 'IsMSShipped') = 0
GROUP BY o.name
ORDER BY SUM(ps.reserved_page_count) DESC
スペースをとっているテーブルを簡単に確認できます。
またEXEC sp_spaceused
、そのDB内で実行すると、2つの結果セットが返されます。1つ目は、ファイルシステムにデータファイル用に割り当てられたスペースの合計とその量を示し、2つ目は、割り当てられたスペースのどの程度がデータページ、インデックスページに使用されているか、または現在使用されていないかを示します。
sp_spaceused
特定のオブジェクトが使用するスペースも返すため、これをループして分析用のテーブルを作成できます。
-- TEMP TABLES FOR ANALYSIS
CREATE TABLE #tTables (sName NVARCHAR(MAX), iRows BIGINT, iReservedKB BIGINT, iDataKB BIGINT, iIndexKB BIGINT, iUnusedKB BIGINT)
CREATE TABLE #tTmp (sName NVARCHAR(MAX), iRows BIGINT, sReservedKB NVARCHAR(MAX), sDataKB NVARCHAR(MAX), sIndexKB NVARCHAR(MAX), sUnusedKB NVARCHAR(MAX))
-- COLLECT SPACE USE PER TABLE
EXEC sp_msforeachtable 'INSERT #tTmp EXEC sp_spaceused [?];'
-- CONVERT NUMBER-AS-TEXT COLUMNS TO NUMBER TYPES FOR EASIER ANALYSIS
INSERT #tTables SELECT sName, iRows
, CAST(REPLACE(sReservedKB, ' KB', '') AS BIGINT)
, CAST(REPLACE(sDataKB , ' KB', '') AS BIGINT)
, CAST(REPLACE(sIndexKB , ' KB', '') AS BIGINT)
, CAST(REPLACE(sUnusedKB , ' KB', '') AS BIGINT)
FROM #tTmp
DROP TABLE #tTmp
-- DO SOME ANALYSIS
SELECT sName='TOTALS', iRows=SUM(iRows), iReservedKB=SUM(iReservedKB), iDataKB=SUM(iDataKB), iIndexKB=SUM(iIndexKB), iUnusedKB=SUM(iUnusedKB) FROM #tTables ORDER BY sName
SELECT * FROM #tTables ORDER BY iReservedKB DESC
-- CLEAN UP
DROP TABLE #tTables
上記のコードは、すべてのテーブルサイズを1つのリストに加えて、合計の1行を出力します。必要に応じて、さまざまなシステムビュー(上記の最初のクエリsys.objects
と同様にsys.dm_db_partition_stats
使用されます。詳細については、http://technet.microsoft.com/en-us/library/ms177862.aspxを参照)を使用して、次のような詳細を取得できます。各インデックスで使用されるスペース。
データファイルには、3つのクラスの未使用領域があります。
- 何にも割り当てられていないもの(これは、
sp_spaceused
オブジェクトが指定されていない最初の結果セットに表示されます)
- オブジェクトに割り当てられている(予約されている)が現在使用されていない(これは、
sp_spaceused
の出力の「未使用」カウントに示されます。
- 部分的に使用されているページでロックされている(これは、すべてが単一のページチャンクに割り当てられており、1ページが8,192バイト長であるため、使用されるように見えます)。これは検出/計算が困難です。これは、次の2つの要因の組み合わせによるものです。
- ページを分割します。データが追加されると、ページが部分的に空のページになることがよくあります(ストレージエンジンは常にページコンテンツを正規化できますが、これは非常に非効率的です)。行が削除されると、ページコンテンツは自動的にパックされません(再度可能ですが、余分なI / O負荷は、一般に、それだけの価値はありません。
- ストレージエンジンは、行を複数のページに分割しません(これは、行あたり8,192バイトの制限が発生するページサイズとともに)。行が固定サイズであり、それぞれが1,100バイトを取る場合、そのテーブルに割り当てられた各データブロックの少なくとも492バイトを「無駄」にします(7行は7,700バイトを消費し、8番目は適合しないため、残りのバイトは適合しません)使用しないでください)。行が広いほど、これは悪化する可能性があります。可変長の行(完全に固定長の行よりもはるかに一般的です)を持つテーブル/インデックスは、一般にかなり良いです(しかし、問題の計算が簡単ではありません)。
ここでのもう1つの注意点は、大きなオブジェクト(TEXT
列、[N]VARCHAR(MAX)
特定のサイズを超える値など)は、ページ外に配置されるため、メイン行データで8バイトを使用して、他の場所にあるデータへのポインターを保持するため)、行あたり8,192バイトの制限を超える可能性があります。
tl; dr:予想されるデータベースサイズの見積もりは、最初に想定するよりもはるかに複雑です。