PostgresのCOPYコマンドで追加した時のindexについて


Coelacanthe現在もアクセス解(ry)。いつぞやか大量のデータを一個一個insertしていたらサーバが落ちちゃった、という記事を書きましたが、その登録方法を COPYコマンドに置き換えてチャレンジ中。まあ結果は速い速い! ・・・ただ、copyコマンドを打ったときに、それまで貼っていたindexもキチンと追加されるのでしょうか?だいたい大量のデータをcopyするときって「drop index->copy->create index が速い」という記事ばかりなので、drop index しなかった場合の情報があまりないんですよね・・・。「そんなの常識」だからないのか!?

ということで、ちょっと調べてみました。

Creative Commons License photo credit: sybarite48

そうは言っても調べ方がわからなかったので、テーブル・インデックスがどのくらい登録されているかのSQLで判断することにしました。SQL文は以下の通り。

1
2
3
4
5
6
7
8
9
10
11
hogedb=$ SELECT relname
     , relkind
     , reltuples
     , (relpages * 8192) AS relpages
  FROM pg_class
 WHERE (relname='tbl_hogehoge' OR relname='idx_hogehoge');
--結果.
    relname   | relkind |    reltuples     |   relpages
---------------------+---------+-------------+-----------
 tbl_hogehoge | r       | 1.31128e+06 |  87269376
 idx_hogehoge | i       | 1.59062e+06 |  46514176

このテーブル群に copy してみます。

1
2
hogedb=$ copy tbl_hogehoge FROM '/home/hogehoge/test.csv' USING delimiters E'\t';
COPY 0

して、その結果は・・・

1
2
3
4
5
6
hogedb=$ SELECT ...(以下上のSQLと同じ)
--結果.
    relname   | relkind |    reltuples     |   relpages
---------------------+---------+-------------+-----------
 tbl_hogehoge | r       | 1.90874e+06 |  126771200
 idx_hogehoge | i       | 1.90874e+06 |  89030656

おっ?増えてる。どうやら COPY コマンドを使った場合でも index はきちんとつくられるようです。

本音を言えば pg_bulkload とか使ってみたいんだけど、今のマシンの postgres を再起動しなきゃいけないとか、そもそもインストール時に SSL のライブラリが古いよーとかいろいろ問題発生中なので、次のサーバ立ち上げ時に持ち越し。

pg_bulkload って COPY 中にエラーがあった行をスキップしてくれるらしいですね。いいなぁ、使ってみたい!