当然、マニュアルは正しいです。しかし、それだけではありません。
1つは、ディスク上のサイズ(実際にはディスクに格納されていない場合でも、テーブル内)がメモリ内のサイズと異なる場合があります。ディスクでは、マニュアルに記載されているように、varchar
126バイトまでの短い値のオーバーヘッドが1バイトに削減されます。ただし、メモリのオーバーヘッドは常に4バイトです(個々の値が抽出されると)。
同じことが当てはまりますtext
、varchar
、varchar(n)
またはchar(n)
その以外- char(n)
空白埋めにあるn
文字、あなたが正常にそれを使用する必要はありません。その有効サイズn
は、バイトではなく最大文字数を示すため、マルチバイトエンコーディングでも変わります。
までの文字列のn
長さの文字(バイトではありません)。
それらはすべてvarlena
内部で使用します。
"char"
(二重引用符付き)は別のクリーチャーであり、常に1バイトを占有します。
型指定されていない文字列リテラル('foo'
)には、1バイトのオーバーヘッドがあります。型付きの値と混同しないでください!
でテストしpg_column_size()
ます。
CREATE TEMP TABLE t (id int, v_small varchar, v_big varchar);
INSERT INTO t VALUES (1, 'foo', '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890');
SELECT pg_column_size(id) AS id
, pg_column_size(v_small) AS v_small
, pg_column_size(v_big) AS v_big
, pg_column_size(t) AS t
FROM t
UNION ALL -- 2nd row measuring values in RAM
SELECT pg_column_size(1)
, pg_column_size('foo'::varchar)
, pg_column_size('12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890'::varchar)
, pg_column_size(ROW(1, 'foo'::varchar, '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890'::varchar));
id | v_small | v_big | t
----+---------+-------+-----
4 | 4 | 144 | 176
4 | 7 | 144 | 176
ご覧のように:
- 3バイトの文字列「foo」は、ディスクで4 バイト、RAMで7バイトを占有します(1バイト対4バイトのオーバーヘッド)。
- 140バイトの文字列「123 ...」は、ディスクとRAMの両方で144バイトを占有します(常に4バイトのオーバーヘッド)。
- のストレージに
integer
はオーバーヘッドがありません(ただし、パディングを課す可能性があるアライメント要件があります)。
- 行には、タプルヘッダー用に24バイトの追加オーバーヘッドがあります(さらに、ページヘッダー内のアイテムポインター用にタプルごとに4バイトが追加されます)。
- そして最後になりましたが
varchar
、行のサイズからわかるように、小のオーバーヘッドは行から抽出されていませんが、まだ1バイトだけです。(そのため、行全体を選択する方が少し速い場合があります。)
関連: