0
私は、pythonとsqlalchemyを使用してデータベーステーブルを作成する関数を持っています。この機能は今のところかなり遅く17分ほどかかっています。私は主な問題は、私は新しいテーブルを構築するために2つの大きなデータセットをループしていると思います。私は以下のコードにレコード数を含めました。pythonとsqlalchemy関数を高速化
これをスピードアップするにはどうすればよいですか?入れ子にされたforループを1つの大きなsqlalchemyクエリに変換する必要がありますか?私はpycharmでこの機能をプロファイリングしましたが、結果を完全に理解しているかどうかはわかりません。
def populate(self):
"""Core function to populate positions."""
# get raw annotations with tag Org
# returns 11,659 records
organizations = model.session.query(model.Annotation) \
.filter(model.Annotation.tag == 'Org')\
.filter(model.Annotation.organization_id.isnot(None)).all()
# get raw annotations with tags Support or Oppose
# returns 2,947 records
annotations = model.session.query(model.Annotation) \
.filter((model.Annotation.tag == 'Support') | (model.Annotation.tag == 'Oppose')).all()
for org in organizations:
for anno in annotations:
# Org overlaps with Support or Oppose tag
# start and end columns are integers
if org.start >= anno.start and org.end <= anno.end:
position = model.Position()
# set to de-duplicated organization
position.organization_id = org.organization_id
position.disposition = anno.tag
# look up bill_id from document_bill table
document = model.session.query(model.document_bill)\
.filter_by(document_id=anno.document_id).first()
position.bill_id = document.bill_id
position.document_id = anno.document_id
model.session.add(position)
logging.info('org: {}, disposition: {}, bill: {}'.format(
position.organization_id, position.disposition, position.bill_id)
)
continue
logging.info('committing to database')
model.session.commit()
すでに動作しているコードの改善については、[codereview.se]よりもStack Overflowより適しています。 – jwodder
'bill_id'を取得するために少なくとも11,659 * 2947 = 34,359,073クエリを実行しています。どのように*遅くない*ことができますか? 'model.session.commit()'もすべての 'organization'と' annotations'を期限切れにします。つまり、内部ループ 'anno'が' org'の最初の反復のたびに一度リフレッシュされ、11,658 * 2947 = 34,356,126クエリ合計68,715,199件のクエリであり、その大半は無駄な作業です。ループ外の単一のクエリで 'document_bill'をクエリし、コミット時に' annotations'を期限切れにしないようにすることができます。最後に、インサートを一括して実行できるかどうかを確認します。 – univerio
ありがとう! model.session.commit()を外側のループに移動してみましょう。つまり、最後に1回実行されます。私はループの外でdocument_billクエリーをどのように動かすことができるのか理解していません。ループ内で提供されているanno.document_idの現在の値に依存するためです。 – Casey