2013-05-24 299 views
15

ファイル内で受け取ったデータで、列の値を定期的に増分する必要があります。テーブルに> 400000の行があります。これまでのところ、私の試みはすべてパフォーマンスが非常に悪くなりました。 私は私の要件を反映した実験書かれています:sqlalchemy一括更新パフォーマンスの問題

#create table 
engine = create_engine('sqlite:///bulk_update.db', echo=False) 
metadata = MetaData() 

sometable = Table('sometable', metadata, 
    Column('id', Integer, Sequence('sometable_id_seq'), primary_key=True), 
    Column('column1', Integer), 
    Column('column2', Integer), 
) 

sometable.create(engine, checkfirst=True) 

#initial population 
conn = engine.connect() 
nr_of_rows = 50000 
insert_data = [ { 'column1': i, 'column2' : 0 } for i in range(1, nr_of_rows)] 
result = conn.execute(sometable.insert(), insert_data) 

#update 
update_data = [ {'col1' : i, '_increment': randint(1, 500)} for i in range(1, nr_of_rows)] 

print "nr_of_rows", nr_of_rows 
print "start time : " + str(datetime.time(datetime.now())) 

stmt = sometable.update().\ 
     where(sometable.c.column1 == bindparam('col1')).\ 
     values({sometable.c.column2 : sometable.c.column2 +  bindparam('_increment')}) 

conn.execute(stmt, update_data) 

print "end time : " + str(datetime.time(datetime.now())) 

私が得る時間はこれらです:

nr_of_rows 10000 
start time : 10:29:01.753938 
end time : 10:29:16.247651 

nr_of_rows 50000 
start time : 10:30:35.236852 
end time : 10:36:39.070423 

はそう行の400000+量があまりにも時間がかかりますことを。

私はsqlalchemyを新しくしましたが、私は多くの読書を行いました。私が間違っていることを理解できません。

ありがとうございます!

答えて

13

単一のクエリで一括更新を行うことで、正しいアプローチを採用しています。

テーブルがインデックスがsometable.column1にないため、その時間がかかるのは理由です。列idには主索引のみがあります。

更新クエリでは、レコードを識別するWHERE句でsometable.column1を使用します。したがって、データベースはすべての単一列更新のためにすべてのテーブルレコードをスキャンする必要があります。アップデートを行うことが

あなたは, index=Trueでcolumn1の定義にインデックス作成を追加するには、テーブルのスキーマ定義のコードを更新する必要がはるかに高速に実行します。

sometable = Table('sometable', metadata, 
    Column('id', Integer, Sequence('sometable_id_seq'), primary_key=True), 
    Column('column1', Integer, index=True), 
    Column('column2', Integer), 
) 

私は私のマシンで更新されたコードをテストした - それは< 2秒かかりましたプログラムを実行する。

あなたの質問の説明にご意見 - あなたの問題を再現するために必要なすべてのコードを入れてください。

+0

すばらしい、ありがとう!私は索引付けについて聞いたことがありましたが、私はそれがはるかに大きな音量でしか演奏されないと考えました。すべて今クリアする、歓声! – devboell