私は490 M行と55 GBのテーブルスペースを持つテーブルを持っているので、行あたり約167バイトです。テーブルには、VARCHAR(100)
、DATETIME2(0)
、およびSMALLINT
の3つの列があります。 VARCHAR
フィールドのテキストの平均長は約21.5であるため、生データは1行あたり約32バイトである必要があります。VARCHAR
は22 + 2、DATETIME2
は6、2 16ビット整数の場合。
上記のスペースはデータのみであり、インデックスではないことに注意してください。プロパティで報告された値を使用しています|ストレージ|全般|データスペース。
もちろん、someのオーバーヘッドが必要ですが、特に大きなテーブルの場合、行あたり135バイトは多くのように見えます。これはなぜでしょうか?他の誰かが同様の乗数を見たことがありますか?必要な追加スペースの量に影響を与える可能性のある要因は何ですか?
比較のために、2つのINT
フィールドと100万行のテーブルを作成してみました。必要なデータスペースは16.4 MBでした。8バイトの生データと比較して、行あたり17バイトです。実際のテーブルと同じテキストが入力されたINT
とVARCHAR(100)
を使用した別のテストテーブルは、行あたり39バイト(44 K行)を使用します。
したがって、実動テーブルにはかなり多くのオーバーヘッドがあります。大きいからですか?インデックスのサイズはおおよそN * log(N)になると思いますが、実際のデータに必要なスペースが非線形である理由はわかりません。
すべてのポインタを事前に感謝します!
編集:
リストされているフィールドはすべてNOT NULL
です。実際のテーブルのVARCHAR
フィールドとDATETIME2
フィールドには、この順序でクラスター化されたPKがあります。 2つのテストでは、最初のINT
は(クラスター化された)PKでした。
重要な場合:テーブルはpingの結果の記録です。フィールドは、URL、ping日付/時間、ミリ秒単位の待機時間です。データは常に追加され、更新されることはありませんが、データは定期的に削除され、URLごとに1時間あたり数レコードだけに削減されます。
編集:
非常に興味深い答え here は、読み取りと書き込みが多いインデックスの場合、再構築は有益ではない可能性があることを示唆しています。私の場合、消費される領域が問題になりますが、書き込みパフォーマンスがより重要な場合は、たるんだインデックスを使用する方がよいでしょう。
元の質問のコメントでの議論の後、この場合、失われたスペースはクラスター化されたキーの選択が原因であると思われます。
これらの状況では、sys.dm_db_index_physical_statsを使用して断片化の状態を常に確認する価値があります。
編集:コメントの更新後
(クラスター化インデックスの再構築前の)平均ページ密度は24%で、元の質問と完全に一致しています。ページは1/4の空き容量しかなかったため、合計サイズはrawデータサイズの4倍でした。
ディスク上の構造にはオーバーヘッドがあります。
2 x 4バイトのint列を取ると、
すごい17バイト!
元のテストテーブルのようにオーバーヘッドが多い2番目のテストテーブルについても同じことができます。
なぜ違いますか?さらに(私はこれらにリンクしません)
@updateusage = 'true'
を指定してsp_spaceusedを実行しますこれを参照してください: SQL Server:1つの8 KBページを満たすテーブルを作成する方法?
SOから:
時間の経過とともにデータ型が変更されましたか?可変長列は削除されましたか?インデックスは頻繁にデフラグされていますが、再構築されていませんか?多数の行が削除されたか、多数の可変長列が大幅に更新されましたか?良い議論 ここ 。