4

私はかなり長いクエリを持っています (以前は 7 つの結合でしたが、現在は 7 つの副選択です。なぜなら、生の SQL では 7 つの副選択がかなり高速だったからです。サブセレクトでは 0.05 ~ 0.1 秒に対して 1 分)

私が言ったように、データベースで実行すると、実行に.05-.1秒かかります。単に使用session.execute()すると、1 分以上遅くなります。

何か私にできることはありますか?

さらに情報が必要な場合はお知らせください-これは一般的なsqlalchemyのことだと思います-たとえば、sqlalchemyがmysqlに任せるのではなく、クエリプランを設定しているようです? または...?

編集:両方で説明を実行しましたが、sqlalchemy が「一時的な使用; ファイルソートの使用」をextra列に追加することを除いて、それらは同じように見えます。それが速度を遅らせているのですか?それをやめさせるにはどうすればよいですか?

編集 2: 間違いなく sqlalchemy。SA セッションの代わりに MySQL カーソルを使用して実行しようとしたところ、同じ 0.05 秒のランタイムが得られました。

編集3:

エンジンを作成するコード:

engine_ro = create_engine(
    config.ro_database_url, #string with username, password, db
    pool_size=config.database_pool_size, #int
    max_overflow=config.database_max_overflow, #int
    pool_timeout=config.database_timeout, # int
    echo=config.database_echo, #False
    echo_pool=config.database_echo, #same as echo #False
    listeners=[GoneAway()] if config.database_use_listeners else None)

whereは、接続を確認するためにGoneAway()a を実行するメソッドです。SELECT 1

セッション オブジェクトを作成するには:

SessionRO = scoped_session(sessionmaker(bind=engine_ro, autocommit=False))

ここでscoped_session、 およびsessionmakerは sqlalchemy 関数です。

次に、クエリを実行するコード:

session = SessionRO()
results = session.execute(sql, params)

EDIT 4:誰かが疑問に思っている場合に備えて、ビットをコメントアウトしても、listenersまだ遅いです。sessionmakerscoped_session なしで使用する場合も同様です。

4

4 に答える 4

4

sqlalchemyクエリプランやその他の凝ったものは設定しません。SQL を生成し、DB-API-2.0 接続を介して送信するだけです。executeそのため、生成されるステートメントと同じステートメントで明示的に呼び出すと、sqlalchemyまったく同じように実行されます。

どのクエリsqlalchemyが生成されているかを確認する最も簡単な方法は、呼び出しecho=Trueで追加のパラメーターとして渡すことです。create_engine

あなたの場合、によって生成されたクエリはsqlalchemy、int ではなく文字列で整数パラメーターをテストしていたため、実際には手動クエリとは異なりました。


* これは 100% 保証されているわけではありません。DB-API-2.0connect関数の接続パラメーターがすべて同じであること、およびステートメントをsqlalchemy実行していないことを確認する必要があります。PRAGMAただし、クエリ自体をテストするのとほぼ同じ方法でそれらをテストできます。

于 2013-05-14T19:27:43.750 に答える
0

コンソール版では、正しいものを貼り付けていました。
SqlAlchemy バージョンでは、string を持つ int パラメーターに対してテストしていました。

于 2013-05-14T18:52:35.883 に答える