「カラムテトリス」
実際には、何かを行うことができます 、しかしこれはより深い理解が必要です。キーワードは配置パディングです。 。すべてのデータ型には特定の配置要件があります。
列間のパディングによって失われるスペースを最小限に抑えることができます それらを有利に注文することによって。次の(極端な)例では、多くの物理ディスクスペースが無駄になります。
CREATE TABLE t (
e int2 -- 6 bytes of padding after int2
, a int8
, f int2 -- 6 bytes of padding after int2
, b int8
, g int2 -- 6 bytes of padding after int2
, c int8
, h int2 -- 6 bytes of padding after int2
, d int8)
24バイトを節約するには 行ごとに、代わりに使用します:
CREATE TABLE t (
a int8
, b int8
, c int8
, d int8
, e int2
, f int2
, g int2
, h int2) -- 4 int2 occupy 8 byte (MAXALIGN), no padding at the end
db<>ここでフィドル
古いsqlfiddle
経験則として、最初に8バイトの列を配置し、次に4バイト、2バイト、および1バイトの列を最後に配置すると、間違いはありません。
boolean
、 uuid
(!)および他のいくつかのタイプでは、位置合わせのパディングは必要ありません。 テキストコード> 、
varchar
およびその他の「varlena」(可変長)タイプ名目上 「int」アライメントが必要です(ほとんどのマシンで4バイト)。しかし、ディスク形式では(RAMとは異なり)アライメントパディングは観察されませんでした。最終的に、私はソースコードのメモに説明を見つけました:
また、「パックされた」varlenasを保存するときに、公称位置合わせに違反することを許可していることにも注意してください。 TOASTメカニズムは、ほとんどのコードからそれを隠すように処理します。
したがって、「int」アラインメントは、単一の先頭の長さバイトを含む(おそらく圧縮された)データが127バイトを超える場合にのみ適用されます。次に、varlenaストレージは先頭の4バイトに切り替わり、「int」アライメントが必要になります。
通常、 "column tetris" を再生すると、行ごとに数バイト節約できます。 。ほとんどの場合、これは必要ありません。しかし、数十億行の場合、簡単に数ギガバイトを意味する可能性があります。
関数pg_column_size()
を使用して、実際の列/行のサイズをテストできます。 。
一部のタイプは、ディスクよりもRAMのスペースを多く占有します(圧縮または「パック」形式)。 pg_column_size()
を使用して同じ値(または値の行とテーブルの行)をテストすると、テーブルの列よりも定数(RAM形式)の方が大きな結果を得ることができます。 。
最後に、一部のタイプは、圧縮または「トースト」(ライン外に保存)、あるいはその両方を行うことができます。
タプル(行)あたりのオーバーヘッド
アイテム識別子の行ごとに4バイト-上記の考慮事項の対象ではありません。
タプルヘッダーの場合は少なくとも24バイト(23 +パディング)。データベースページレイアウトのマニュアル:
固定サイズのヘッダー(ほとんどのマシンで23バイトを占める)があり、その後にオプションのnullビットマップ、オプションのオブジェクトIDフィールド、およびユーザーデータが続きます。
ヘッダーとユーザーデータ間のパディングについては、 MAXALIGN
を知っている必要があります サーバー上-通常、64ビットOSでは8バイト(または32ビットOSでは4バイト)。よくわからない場合は、 pg_controldata
を確認してください。 。
Postgresバイナリディレクトリで次を実行します 決定的な答えを得るには:
./pg_controldata /path/to/my/dbcluster
マニュアル:
実際のユーザーデータ(行の列)は、
t_hoff
で示されるオフセットから始まります。 、これは常にMAXALIGN
の倍数である必要があります プラットフォームの距離。
したがって、通常、データを8バイトの倍数でパックすることで最適なストレージを取得します。
投稿した例では何も得られません 。すでにしっかりと詰まっています。最後のint2
の後の2バイトのパディング 、最後に4バイト。最後にパディングを6バイトに統合しても、何も変更されません。
データページごとのオーバーヘッド
データページのサイズは通常8KBです。このレベルでもいくつかのオーバーヘッド/肥大化:残りは別のタプルを収めるのに十分な大きさではなく、さらに重要なことに、デッドローまたは FILLFACTOR
で予約されたパーセンテージ 設定。
考慮すべきディスク上のサイズには、他にもいくつかの要因があります。
- Herokuの5MBのPostgreSQLにいくつのレコードを保存できますか?
- PostgreSQLでNULLを使用しない場合でも、ヘッダーでNULLビットマップを使用しますか?
- 読み取りパフォーマンスのためのPostgreSQLの構成
配列タイプ?
配列を使用 評価しているように入力すると、24バイトのオーバーヘッドが追加されます タイプのために。さらに、配列要素は通常どおりスペースを占有します。そこに得るものは何もありません。