[pgsql-jp: 27292] Re: 見積り表領域と
sugita @ sra.co.jp
sugita @ sra.co.jp
2002年 9月 4日 (水) 13:24:52 JST
杉田です。
From: sugita @ sra.co.jp
Date: Mon, 26 Aug 2002 22:01:34 +0900 (JST)
;;; インデックスのサイズについては、参照されている資料が思いっ切り間違っていまし
;;; た。後で、直したのを投稿します。
間違いは、インデックス付きのテーブルにデータを投入した場合とインデックスを再
構築した場合で、空間使用率が異なることです。最初のは、データを投入してからイン
デックスを作成していました。両方の結果、アラインメントへの言及などを修正しまし
た。
================================================================
ディスク領域の見積りの概要
$Revision: 1.13 $
1. 圧縮のない場合のテーブルサイズの概算見積もり方法
int4 の 1 フィールドのテーブルで 10 万レコードの場合の見積もりは以下のよう
になります。
32 + 4 + 4 + 4 = 44 … レコードサイズ。
各行のヘッダ 32 バイト (7.3 では 28 バイト)
+ フィールド数 32 で、NULL 値がある場合の NULL ビットマスク
+ ページ内のタプルへのポインタ
+ int4 のサイズ
8192 / 40 = 187 … ブロックあたりのレコード数。
データベースページ数 /レコードサイズ。
100000 / 187 = 535 … ブロック数。
レコード数 / ブロックあたりのレコード数。
535 * 8192 = 4382720 … テーブルファイルサイズ。
ブロック数 * ブロックサイズ。
実測例を以下に示します。
ファイルサイズ
レコード数 7.2 7.3
========== =================== ===================
100000 4022272 3612672
200000 8036352 (+4014080) 7225344 (+3612672)
300000 12050432 (+4014080) 10829824 (+3604480)
400000 16064512 (+4014080) 14442496 (+3612672)
500000 20078592 (+4014080) 18046976 (+3604480)
約 -8% の誤差は、ページ内のページ管理情報とNULL 値のための NULL ビットマス
クが全行に必要として見積もったため。
圧縮のある場合には、以降の「データ圧縮」の項を適用します。
フィールドが NULL 値かどうかを判断するNULL ビットマスクによって、NULL 値の
場合には値を格納する領域はタプル内に取られません。従って、ビットフラグが存
在し、すべてのフィールドについてタプル内に格納領域が必要として見積もりをす
るならば、実測値を下回る可能性は少なくなります。
NULL ビットマスクサイズは全フィールドが NULL の場合には 0 で、32 フィール
ドごとに 4 バイトずつ増加します。つまり、1〜32 フィールドで 4 バイト、33〜
64フィールドで 8 バイトとなります。
2. インデックスサイズの見積もり (btree)
レコード辺りのオーバーヘッドが 12 としテーブルと同様に算出します。
12 + 4 = 16
8192 / 16 = 512
100000 / 512 = 195
195 * 8192 = 1597440
実測例を以下に示します。
レコード数 インデックスファイルサイズ フリースペース B 木レベル
========== ========================== ============== ==========
100000 2506752 886028 2
200000 5013504 (+2506752)
300000 7512064 (+2498560)
400000 10010624 (+2498560)
500000 12509184 (+2498560)
約 64% の空間使用率で、B 木の空間使用率としては問題ありません。
上記では、インデックスの付いたテーブルへデータを投入しています。インデック
スを再構築するとフリースペースサイズが減少し空間使用率が増加します。
レコード数 インデックスファイルサイズ フリースペース B 木レベル
========== ========================== ============== ==========
100000 1810432 195488 2
200000 3612672 +1802240
300000 5406720 +1794048
400000 7200768 +1794048
500000 8994816 +1794048
こちらの場合の空間使用率は、約 88% です。
3. 主なデータ型の格納サイズ
データ型名 データベース上のバイト数
---------------------- -------------------------------
smallint 2
integer 4
bigint 8
decimal 圧縮 (サイズは値の桁数に依存)
numeric 圧縮 (同上)
real 4
double precision 8
serial 4 (7.2 では 8 の serial あり)
boolean 1
character(n) 4 + データ長、圧縮
character varying(n) 〃
text 〃
timestamp 8
time with time zone 8
interval 12
date 4
time 8
time with time zone 12
注) フィールド間は、通常は 4 バイトアラインメント。
4. データ圧縮
以下の 3 つのデータ型の圧縮率は同一です。
character(n)
character varying(n)
text
以下の 2 つのデータ型の圧縮率は同一です。また、圧縮率は値の桁数の 1/2 の長
さの text の圧縮率とほぼ同等です。
decimal
numeric
text の圧縮率の例は以下の通りです。
ランダムな 1000 文字の漢字文字列 (圧縮率約 1/30)
レコード数 テーブルファイルサイズ
========== ======================
10000 688128
20000 1368064 +679936
30000 2048000 +679936
40000 2736128 +688128
50000 3416064 +679936
ランダムな 2000 文字の英字文字列 (圧縮率約 1/30)
レコード数 テーブルファイルサイズ
========== ======================
10000 688128
20000 1368064 +679936
30000 2048000 +679936
40000 2736128 +688128
50000 3416064 +679936
5. データベースのサイズに影響する主な要因
前述の見積りは、データの初期投入でのファイルサイズで、データベースの運用と
共に PostgreSQL の追記型の影響によって、データベースのサイズは、動的に変化
します。その主な要因は以下のようになります。
1) 更新の頻度 (テーブルファイルとインデックスファイルに影響)
2) ソートを必要とするクエリーや JOIN のワークファイル
explain によるソート領域の見積り。
3) WAL ファイルサイズ
データベース領域より大きくなる場合もあります。
4) REINDEX のワークファイル
5) バックアップ領域などの付随的なワーク領域
6) テンポラリテーブルの使用の有無
7) 7.1 以前のコミットログは単調増加し、initdb 以外では縮小できないない
ので、長期間の運用では注意。
従って、静的なサイズの見積もりに加え、運用シナリオを作成し、実験を行ってディ
スク使用量を見積もります。特に 1) は PostgreSQL の追記型という特徴を反映し
た影響を受けるので、VACUUM の適用と合わせて運用設計を行います。また、運用
中のディスク領域の監視も必要です。
6. 参考資料
1) データ圧縮
「PostgreSQL 完全攻略ガイド 第 3 版」の P.94〜95。
7.2 では octet_length の戻り値が変更され圧縮された値でなく、データ
の実際のバイト数となっていることに注意。
2) データのデータベース上のバイト数
「PostgreSQL 7.1.3 ユーザーズガイド」の「3. データ型」を参照。
3) doc/FAQ_japanese
PostgreSQL(ポストグレス・キュー・エル)についてよくある質問とその解答(FAQ)
4.7) 一般的なテキストファイルからデータを保存するには、データベースの
ディスク容量はどのくらい必要です?
4) 「POSTGRESQL PERFORMANCE TUNING」の P. 39〜P. 41。
http://candle.pha.pa.us/main/writings/pgsql/performance.pdf
付録 1. リレーションの種類
種類 内容
================ ==============================================================
テーブル RDB のテーブルのレコードが格納されるヒープファイル。
インデックス アクセスメソッド。btree、rtree、hash、gist が用意されている。
TOAST テーブル 1 カラムの最大格納後データサイズを 1G にするために使用される
データ格納テーブル。必要に応じて圧縮も行われる。
シーケンス ユニークな連番を生成するためのテーブル。シーケンスオブジェク
トごとにひとつのレコードのみが存在し、追記型として扱われない。
ビュー ルールによって実装された参照用ビュー。現時点では、更新可能で
はない。
特殊リレーション pg_xactlock のみで、トランザクションの排他制御用に使用される。
ディスク上のデータ格納ファイルは存在しない。
付録 2. ディスクファイル上のページファイル構造
ページヘッダ ラインポインタ ラインポインタ
+----------------+---------------+-----------------+
| PageHeaderData | pd_linp[1] | pd_linp[2] ... |
+-----------+----+---------------+-----------------+
| ... pd_linp[n] | |
+----------------+ |
| ^ pd_lower |
| フリースペース |
| v pd_upper |
| +------------------------------------+
| | タプルn ... |
+------------++--------+---------+-----------------+
|... タプル3 | タプル2 | タプル1 | 特殊データ |
+------------+---------+---------+-----------------+
^ pd_special
PageHeaderData の構造
データ型 メンバ名 内容
============= ========== ================================================
XLogRecPtr pd_lsn ログシーケンス番号
StartUpID pd_sui スタートアップ識別子
LocationIndex pd_lower フリースペースの開始オフセット
LocationIndex pd_upper フリースペースの末端オフセット
LocationIndex pd_special 特殊データの開始オフセット。テーブルと TOAST テー
ブルの場合には、使用されないためページ終端のオフセッ
ト。インデックスの場合には、アクセスメソッドで必要
とする任意のデータ、例えば、btree の場合には、前後
親の 3 つのブロック番号。シーケンスの場合には、シー
ケンスを示すマジックナンバー 0x00001717。
OpaqueData pd_opaque アクセスメソッド固有データ、現在ページサイズを保存。
ItemIdData pd_linp[1] ラインポインタ配列の先頭要素
================================================================
Kenji Sugita
pgsql-jp メーリングリストの案内