我有一个相当长的查询(是 7 个连接,现在是 7 个子选择,因为在原始 sql 中,7 个子选择要快得多——我什至不知道如果我让它运行 7 个连接什么时候完成,但比1 分钟与 0.05-.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)
whereGoneAway()
是一个执行 aSELECT 1
来检查连接的方法。
创建会话对象:
SessionRO = scoped_session(sessionmaker(bind=engine_ro, autocommit=False))
wherescoped_session
和sessionmaker
是 sqlalchemy 函数。
然后,执行查询的代码:
session = SessionRO()
results = session.execute(sql, params)
编辑 4:如果有人想知道,如果我注释掉这listeners
一点,它仍然很慢。同样,如果我只使用sessionmaker
没有 scoped_session。