[pgsql-jp: 37724] Re: INDEXを残したまま大量データを高速に挿入したい
TANIDA Yutaka
tanida @ sraoss.co.jp
2006年 11月 27日 (月) 13:31:38 JST
谷田です。
On Tue, 21 Nov 2006 17:02:38 +0900
河本陽一 <komoto.yoichi @ kcc.co.jp> wrote:
> 毎日1回、大量のデータ(1000万件)をひとつのトランザクションで投入し
> ようとしています。PostgreSQLは、7.4を使用しています。
> 投入速度が遅いため、投入時は最低限のINDEX以外を削除することで性能
> が出るようになりました。
> しかし、データ投入の間(時間にして約8時間20分)は、INDEXがないために
> SELECTの性能が出なくなってしまいます。
> これでは使用する上で困るので、回避方法を探しています。
現実的な方法はいろいろ出ているようですので、別の怪しい方法をば。基本
的に危険な方法なのでお勧めはしません。まあこういう変わった方法もあるとい
うことで、読み物程度に楽しんでください。
begin;
update pg_class set relhasindex='f' where relname=(該当テーブル名);
データ投入更新
update pg_class set relhasindex='t' where relname=(該当テーブル名);
reindex table (該当テーブル名);
commit;
この方法は、一時的にインデックスを無効にすることで、データ投入速度を高速
化するものです。当然、投入するデータがデータ全体に占める割合が多ければ多
いほど高い効果があります。
こうすると、reindexする間だけAccessExclusiveLockのためアクセスできなくな
りますが、データ更新は高速になります。ただし、以下の点に留意してくださ
い。
-pg_classテーブルをいじりますので、relname以外に条件が必要なことがありま
す。この説明はここでは省略します。
-データ投入更新時に、インデックスを無効にしたテーブルでのインデックスが
必要な場合、他の接続からselect すれば、そちらではインデックスが使えま
す。同じ接続からselectしても、インデックスは使われません。
-更新後の後処理は絶対に忘れないでください。特にreindexをしないと、イン
デックスの整合性に問題が出ます。
ちなみに、Slony-Iが、subscribe setでデータをコピーする時にこの方法を使っ
て高速化を実現してます。
--
TANIDA Yutaka <tanida @ sraoss.co.jp>
pgsql-jp メーリングリストの案内