使用 sqlalchemy 会话执行 sql 会极大地减慢执行时间

Col*_*een 5 python mysql sql sqlalchemy

我有一个相当长的查询(以前是 7 个连接,现在是 7 个子选择,因为在原始 sql 中,7 个子选择要快得多——我什至不知道如果我让它运行,7 个连接何时完成,但比1 分钟与 0.05-0.1 秒(使用子选择)

当我在数据库上运行它时,正如我所说,执行需要 0.05-.1 秒。只需使用即可session.execute()将速度减慢至一分多钟!

有什么我可以做的吗?

如果您需要更多信息,请告诉我 - 我有点怀疑这是一个通用的 sqlalchemy 事情 - 就像 sqlalchemy 正在设置一个查询计划而不是让 mysql 来做它?或者...?

编辑:对两者都进行了解释,它们看起来相同,只是 sqlalchemy 在列中添加了“使用临时;使用文件排序” extra。这就是减慢速度的原因吗?我怎样才能阻止它这样做?

编辑2:绝对是sqlalchemy。我尝试使用 MySQL 游标而不是 SA 会话来执行,并获得相同的 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)
Run Code Online (Sandbox Code Playgroud)

其中是执行 a以检查连接的GoneAway()方法。SELECT 1

创建会话对象:

SessionRO = scoped_session(sessionmaker(bind=engine_ro, autocommit=False))
Run Code Online (Sandbox Code Playgroud)

其中scoped_sessionsessionmaker是 sqlalchemy 函数。

然后,执行查询的代码:

session = SessionRO()
results = session.execute(sql, params)
Run Code Online (Sandbox Code Playgroud)

编辑4:如果有人想知道,如果我注释掉这listeners一点,它仍然很慢。如果我只使用没有scoped_session 的情况也是如此sessionmaker

aba*_*ert 4

sqlalchemy不设置查询计划或其他任何奇特的东西。它只是生成 SQL 并通过 DB-API-2.0 连接发送它。因此,如果您execute使用生成的相同语句显式调用sqlalchemy,它将以完全相同的方式运行。*

查看生成的查询的最简单方法是在调用中作为额外参数sqlalchemy传递。echo=Truecreate_engine

在您的情况下,生成的查询sqlalchemy实际上与您的手动查询不同,因为它使用字符串而不是 int 测试整数参数。


* 这并不能 100% 保证;您必须确保 DB-API-2.0connect函数中的任何连接参数都相同,并且您既没有执行也没有sqlalchemy执行任何PRAGMA语句。但是您可以用与测试查询本身相同的方式来测试它们。