[pgsql-jp: 27738] Re: 見積り表領域と

KAWAI,Takanori GCD00051 @ nifty.ne.jp
2002年 10月 25日 (金) 15:12:25 JST


川合孝典です。

仕事の関係で7.1.3での表領域の使用量の見通しを計算していた
のですが、その関係でいくつか気になった点について指摘させて
いただきます。
自分でまとめようかと思ってはいるのですが、まだちょっと混乱気味。

----- Original Message -----
From: <sugita @ sra.co.jp>
To: <pgsql-jp @ ml.postgresql.jp>
Sent: Wednesday, September 04, 2002 1:24 PM
Subject: [pgsql-jp: 27292] Re: 見積り表領域と


>   杉田です。
(中略)
> ================================================================
>
>
>      ディスク領域の見積りの概要
>
>
> $Revision: 1.13 $
>
> 1. 圧縮のない場合のテーブルサイズの概算見積もり方法
>
>     int4 の 1 フィールドのテーブルで 10 万レコードの場合の見積もりは以下の
よう
>     になります。
>
> 32 + 4 + 4 + 4 = 44 … レコードサイズ。
>
>     各行のヘッダ 32 バイト (7.3 では 28 バイト)
>     + フィールド数 32 で、NULL 値がある場合の NULL ビットマスク
>     + ページ内のタプルへのポインタ
>     + int4 のサイズ
>
> 8192 / 40 = 187 … ブロックあたりのレコード数。
>
>     データベースページ数 /レコードサイズ。
このでの分母の40は44のtypoだと思われます。
さらに英語のFAQ(*1)と日本語のほうとで切り上げ、切捨てで
違っているようです。
日本語(*2)のほうではブロックあたりのレコード数を切り上げにして
いますが、英語のほうではブロックあたりのレコード数は切り捨て、
使用するページ数を切り上げています。
感覚的にも1つのブロックにレコードがいくつ入るかということですから、
切捨てのほうがしっくりきます。

(*1) http://www.ca.postgresql.org/docs/faq-english.html#4.6
(*2) http://www.postgresql.jp/subcommittee/jpugdoc/faq-japanese.html#4.6

ただ、それに基づいて187ではなく186で計算すると。
ブロック数は537.63 => 538, 使用ディスク量: 4,407,296
となり、さらに実測値と違ってきます。

これはNULLビットマスクが常に入るという計算にしているからでは
ないかと思われます。そこで、その分を引いて、これをレコードの大きさを
40として計算すると
 ブロックあたりのレコード数: 204.8 => 204
               使用ページ数  使用ディスク量
100,000 :  490.19 =>  491       4,022,272
200,000 :   980.39 =>  981       8,036,352
300,000 :  1470.58 => 1471       12,050,432
400,000 :  1960.78 => 1961       16,064,512
500,000 :  2450.98 => 2451       20,078,592

(7.3ではヘッダの大きさの関係から => 36)
               使用ページ数  使用ディスク量
 ブロックあたりのレコード数: 227.55 => 227
100000:   440.53 =>  441    3,612,672
200000:   881.06 =>  882    7,225,344
300000:  1321.59 => 1322  10,829,824
400000:  1762.11 => 1763  14,442,496
500000:  2202.64 => 2203  18,046,976

となりピッタリ合致します。

> 4. データ圧縮
圧縮なんですが、7.1.3ではレコードの大きさが2000ぐらいで圧縮がかかるか
かからないかの閾値があるようです。(ヘッダも含めて2040かなと)
1つのTEXTフィールドしか持たないテーブルで試してみたところ、

size=# insert into tbls0(v1) values(rpad('X', 1996, 'X'));
size=# insert into tbls0(v1) values(rpad('X',1997, 'X'));
ize=# select character_length(v1), octet_length(v1) from tbls0;
 char_length | octet_length
-------------+--------------
        1996 |         1996
        1997 |           31

といった具合になりました。
別に1万件を挿入するスクリプトを作って調べてみましたが、
実際に作られるファイルの大きさにも変化がありました。
#vacuum analyzeの後、pg_classをチェック
#$PGDATAのbaseの下に作られたファイルの大きさとも比較

ついでに以下のようなことも試したところ、1項目の大きさというより
レコード全体の大きさが閾値になるのかなと思っております。

create table tbls01(v1 text, v2 text);
insert into tbls01 values(rpad('x', 1000, 'x'), rpad('x', 992, 'X'));
insert into tbls01 values(rpad('x', 1000, 'x'), rpad('x', 993, 'X'));

select character_length(v1), octet_length(v1),
character_length(v2), octet_length(v2) from tbls01;

char_length | octet_length | char_length | octet_length
-------------+--------------+-------------+--------------
        1000 |         1000 |         992 |          992
        1000 |           18 |         993 |          993

実際、今回のシステムではTEXTに入力する部分があり、
そこにどれくらいの量のものが入るのかわからないため、
現状ではまったくの予測しか出せないのかなと思っています。
#それでも商売なので数字は出しますが(^^)

PS.
ただ客先からは「管理上のディスク使用量を予測したい」という
ことなので、pg_classのrelpagesとreltuplesを見て、1レコードあたりの
平均値を求めて、出すようなものも用意する必要があるかなぁと
今は考えています。
#vacuumは、結構頻繁にやってはくれるらしいので、その点では
#ちょっと安心?
===================================================
川合 孝典 (Hippo2000)
   DBI日本語メーリングリスト管理人、Kansai.pm所属
   kwitknr @ cpan.org GCD00051 @ nifty.ne.jp
   http://member.nifty.ne.jp/hippo2000、http://www.hippo2000.info/
perldocの日本語化ならperldocjp:もちろん参加者募集中!
  http://sourceforge.jp/projects/perldocjp
===================================================




pgsql-jp メーリングリストの案内