2016-09-06 6 views
0

次のコードブロックは〜2000行のテーブルをクエリします。ループは20秒かかる!私の限られた知識から、私は2000のクエリを実行しているとは思わないが、ちょうどそれを理解していないだろう。オペレータとそれが舞台裏で何をしているのかを示します。このループをより迅速に実行できるように修正するにはどうすればよいですか?トップレベルのクエリs.tを調整する方法はありますか? 2番目のforループは合計3000件のクエリを作成していません(実際に何が起こっているのでしょうか)。SQLAlchemyの反復処理でのパフォーマンスが悪い

ここでは、実際にこの内部ループが大量の時間消費を引き起こしていることを検証するために作成したコードのテストブロックを示します。選択された最良の答えからの提案を使用

block = [] 
cnt = 0 
for blah in dbsession.query(mytable): 
    tic = time.time() 
    for a in blah.component: 
     cnt += 1 
    block.append(time.time()-tic) 
print "block: %s seconds cnt: %s" % (sum(block), cnt) 

# block: 20.78191 seconds cnt: 3021 

は、forループになった:20-25sそれぞれから行く各コンポーネントの内部ループをもたらし

for blah in dbsession.query(mytable).options(joinedload(mytable.componentA)).options(mytable.componentB)).options(mytable.componentC) 

、0.25 0.59および0.11にsである。クエリ自体には約18秒かかるので、私の合計保存時間は約55秒です。

+0

'blah.component'は何ですか?列?関係? – RazerM

+0

"私は2000クエリを実行しているとは思わない":エンジンに 'echo = True'を記録するか、ログを有効にするべきです。 – RazerM

+0

私はDBに慣れていませんが、私は関係を信じています。これはorm.mapper(a、b、properties = {'component':orm.relationship(othercomponent、secondary = 、primaryjoin = == 、secondaryjoin = == })にリストされています – pyInTheSky

答えて

2

.componentにアクセスするたびに、別のSQLクエリが発行されます。

あなたはRelationship Loading Techniquesで詳細を読むことができますが、次のようにクエリを変更することができ、一度にすべてをロードするために:

from sqlalchemy.orm import joinedload 

dbsession.query(mytable).options(joinedload('component')) 
+0

forループは次のようになります。 dbsession.queryのblahcomponent ...? – pyInTheSky

+0

いいえ、dbsession.query(... 'で、blahのためにSQLAlchemyは' .component'にアクセスして既にロードされていることを知っています) – RazerM

+0

私の感謝の気持ちを表し始める... 21sから0.37s – pyInTheSky