私はPostgresに非常に慣れていないので、私の数学はここから外れる...
これは私のテーブルです:
CREATE TABLE audit (
id BIGSERIAL PRIMARY KEY,
content_id VARCHAR (50) NULL,
type VARCHAR (100) NOT NULL,
size bigint NOT NULL,
timestamp1 timestamp NOT NULL DEFAULT NOW(),
timestamp2 timestamp NOT NULL DEFAULT NOW()
);
1行が占めるスペースを見積もりたいのですが。いくつか読んだ後、私はこれを思いつきました、それは正しいですか?
1 row =
23 (heaptupleheader)
+ 1 (padding)
+ 8 (id)
+ 50 (content_id)
+ 6 (padding)
+ 100 (type)
+ 4 (padding)
+ 8 (size)
+ 8 (timestamp)
+ 8 (timestamp)
= 216 bytes
ローカルのPostgres DBにも同じテーブルを作成しましたが、数値が一致していないようです。
INSERT INTO public.audit(content_id, type, size)
VALUES ('aaa', 'bbb', 100);
SELECT pg_size_pretty( pg_total_relation_size('audit') ); -- returns 24 kb
INSERT INTO public.audit(content_id, type, size)
VALUES ('aaaaaaaaaaaaa', 'bbbbbbbbbbbbbb', 100000000000);
SELECT pg_size_pretty( pg_total_relation_size('audit') ); -- still returns 24 kb
Postgresは24 kbのスペースを最初から予約していると思いますが、24 kbを超えると、より多くのデータを入力すると、132バイトずつ増加しますか?しかし、私の中で何かが正しくないことを言います。
Postgres dbで1行が占めるスペースを確認したいので、そこに格納できるデータ量を分析できます。多分私は非常に明白な何かを見逃している。
計算は、裸の最大行サイズに近いです。実際の範囲は、行あたり68〜212バイト、またはインデックスを含めて84〜228バイトです。
最も重要なのは、varchar(n)
が最大長を占める必要がないことです。データ型はvarlena
で内部的に実装されます。これにより、ディスク上の短い文字列に1バイトのオーバーヘッドと、文字列の実際のバイト数が追加されます。
varlena
を使用して実装されたデータ型は、ディスク上に配置パディングを必要としません。
そしてNULL値(content_id
)は事実上無料です。見る:
最後にPRIMARY KEY
制約は、標準のbtreeインデックスを使用して実装されます。これをディスクの合計サイズに追加する必要があります。
したがって、ディスク上の行サイズの計算は次のとおりです。
23バイトのタプルヘッダー 1バイトのパディングまたはnullビットマップ 8バイトのID BIGSERIAL PRIMARY KEY 0〜51バイトのcontent_id VARCHAR(50)NULL 0バイトアラインメントパディング 2〜101バイトタイプVARCHAR(100)NOT NULL ?バイトアラインメントパディング 8バイトサイズbigint NOT NULL 8バイトtimestamp1タイムスタンプNOT NULL 8バイトtimestamp2タイムスタンプNOT NULL --- 分64(6バイトのパディングを含む)-最大208バイト(パディングは不要) +ヒープページの4バイトのアイテム識別子 --- 68-212バイト +インデックスタプル用16バイト --- 84-228バイト
さらに、次の関連する質問で詳しく説明されているように、ヒープページとインデックスページのオーバーヘッドがいくつかあります。
ディスク上の実際の行サイズ(アイテムIDなし):
SELECT pg_column_size(a) AS size_on_disk, *
FROM audit a;
RAMのサイズは異なる場合があります:
SELECT pg_column_size(content_id) AS content_id_size_on_disk
, pg_column_size(content_id || '') AS content_id_size_in_ram
, content_id
FROM audit a;
見る:
約 ...
Postgresは開始するために24 kbのスペースを予約していると思います
ヒープは0バイトから始まります。インデックスは1つのメタページ(8kb)で始まります。最初の行を追加すると、最初のヒープページに最低8 kb、インデックス(最低1メタページ+最初のインデックスページ)に16 kbが表示されます。フィドルの詳細!
db <> fiddle ここ
PostgreSQLのドキュメント と次の StackOverflowの質問/回答 が出発点として適しています。