以前、PythonのPostgreSQL用のドライバがうまくインストール出来ないと記載しましたが、python-develが入って無かっただけっぽいです。
yum install python-devel
で、
① ocpgdb1.0.3
② psycopg2-2.4
③ PyGreSQL-4.0
④ pg8000-1.08
の全てのドライバがinstall可能でした。
上記はPython2.6及び、2.7で確認しましたが、2.7の場合は④のインストールがいじらないとうまくいきませんでした。(詳細はここに記載されています)
で、今回の趣旨はPythonからのBulkInsertを試してみようというものです。
driverですが、前回は④を使いましたが、今回は②psycopg2を使ってみました。
事前に、
CREATE TABLE hash ( id text PRIMARY KEY , value text );
でhashテーブルというのを作っています。
ソースは以下みたいな感じです。
------ bulk insertする実行例 ------
#!/usr/bin/env python
import csv
import psycopg2
import time
if __name__ == '__main__':
start = time.time()
c = psycopg2.connect(host="localhost",user="postgres",password="xxxx",database="testdb")
i = 0
l = []
cur = c.cursor()
reader = csv.reader(open("./neta.csv"))
for row in reader:
id = row[0]
value = row[1]
t = (id,value)
l.append(t)
i += 1
if i % 10000 == 0:
cur.executemany("insert into hash values(%s,%s)",l)
c.commit()
cur = c.cursor()
l = []
c.commit()
c.close()
print time.time()-start
上記を実行すると100万件のinsertに大体200sかかりました。
因みに1件ずつinsertするのは以下のような感じです。
------ bulk insertしない実行例 ------
#!/usr/bin/env python
import csv
import psycopg2
import time
if __name__ == '__main__':
start = time.time()
c = psycopg2.connect(host="localhost",user="postgres",password="xxxx",database="testdb")
i = 0
reader = csv.reader(open("./neta.csv"))
for row in reader:
id = row[0]
value = row[1]
t = (id,value)
cur = c.cursor()
cur.execute("insert into hash values(%s,%s)",t)
i += 1
if i % 10000 == 0:
c.commit()
c.commit()
c.close()
print time.time()-start
これを実行すると100万件のinsertに220sかかりました。
executemany()を使用してもパフォーマンス改善にはさしてつながっていません。しかし、言い方を変えると20sも改善しています。これは通信のオーバヘッド以上に処理に時間がかかっている為、改善効果が大きくは見えないという事でしょう。
前回のpg8000で実施したテストよりもだいぶ高速だった為、pg8000でももう一度試してみました。上記のソースで、
・import psycopg2のところをimport pg8000とする
・psycopg2.connect のところを pg8000.dbapi.connectとする
事でつながるようになります。結果として以前やった結果と変わらずにbulkinsertを使おうが使うまいが、1000s以上かかってしまいます。理由は全く不明ですが、バインド変数とかをpg8000だとうまく使えて無いのかな・・・?
<まとめ>
・fedoraにpostgresqlのドライバをinstallする際はpython-develを入れるのを忘れずに
・psycopg2でbulkinsertの効果を確認したが、さしたる改善効果は無かった。
・pg8000とpsycopg2で大量insertのパフォーマンスを比較すると、psycopg2の方が圧倒的に早い。