2011-11-11 10 views
3

from節の左結合の位置を保存する2つの同一のクエリがあります。一つは、(明確にするため省略)非常に速く、他の実行を非常に遅い実行します:SQLAlchemy + SQLite左結合パフォーマンスの問題

--SLOW 
SELECT DISTINCT b.id 
FROM a LEFT OUTER JOIN b ON a.id = b.id 
     JOIN c ON a.id = c.a_id 
     JOIN d ON c.id = d.c_id 
WHERE d.value = 9; 

--FAST 
SELECT DISTINCT b.id 
FROM a JOIN c ON a.id = c.a_id 
     JOIN d ON c.id = d.c_id 
     LEFT OUTER JOIN b ON a.id = b.id 
WHERE d.value = 9; 

私の問題は、SQLAlchemyのを使用して、私は、クエリの遅いバージョンを作成することができるように見える、ということです。具体的には、私はテーブル継承を使用していますし、次のコードを実行しようとしています:つまり

return session.query(A).\ 
     with_polymorphic(B).\ 
     join(C).\ 
     join(D).\ 
     filter(D.value_id == 9).\ 
     distinct() 

を、私はLEFT JOINをどこのコントロールが作成されている必要はありません。

これについて、SQLiteやSQLAlchemyをよりスマートにする方法を教えてください。

答えて

1

SAに強制的にクエリを変更させる方法はわかりません。しかし、なぜ私はクエリの実行計画に違いがあるのか​​を特定したいと思います。私はあなたが結合列にインデックスを持っている場合、クエリのJOINsの順序は問題ではないと思います。

EXPLAINステートメントを使用して実行計画を確認できます。 The Virtual Database Engine of SQLiteに精通している必要がありますが。それでも、2つの実行計画の違いをすぐに見つけ、SAを騙す代わりにデータベースのパフォーマンスを向上させることができます。
CまたはDも削除して、実行計画の比較をさらに簡単にしてください。

+0

van、あなたは素晴らしいです! 2つの欠落した索引 - そうです。私の厚い見方は、私の参加の半分が常にプライマリ・キーになっていたので、すべてがうまくいったと仮定していました。しかし、結合がキー上にあっただけなので、結合は正しい順序で実行されたときにすばやく実行されます。 –