python - 使用in_()方法后sqlalchemy查询很慢
问题描述
filters.append(Flow.time_point >= datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S'))
filters.append(Flow.time_point <= datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S'))
if domain_name != 'all':
filters.append(Bandwidth.domain_name.in_(domain_name.split('|')))
flow_list = db.session.query(Flow.time_point, db.func.sum(Flow.value).label('value')).filter(*filters).group_by(Flow.time_point).order_by(Flow.time_point.asc()).all()
当 domain_name 为 时查询时间为 3 到 4 秒'all'
,否则查询时间为 5 分钟。我试图向列添加索引,但无济于事。这可能是什么原因?
解决方案
什么时候domain_name
不是'all'
你最终在andCROSS JOIN
之间执行隐式。当您将谓词添加到过滤器列表时,SQLAlchemy 也会将其作为对象。由于两者之间没有显式连接,因此查询最终将类似于:Flow
Bandwidth
IN
Bandwidth
FROM
SELECT flow.time_point, SUM(flow.value) AS value FROM flow, bandwidth WHERE ...
-- ^
-- `- This is the problem
在最坏的情况下,规划器会生成一个查询,该查询首先将来自 的每一行与来自Flow
的每一行连接起来Bandwidth
。如果您的表甚至中等大,那么生成的行集可能会很大。
如果没有看到您的模型,就不可能产生精确的解决方案,但一般来说,您应该在查询中包含正确的连接,如果您包括Bandwidth
:
query = db.session.query(Flow.time_point, db.func.sum(Flow.value).label('value'))
filters.append(Flow.time_point >= datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S'))
filters.append(Flow.time_point <= datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S'))
if domain_name != 'all':
query = query.join(Bandwidth)
filters.append(Bandwidth.domain_name.in_(domain_name.split('|')))
flow_list = query.\
filter(*filters).\
group_by(Flow.time_point).\
order_by(Flow.time_point.asc()).\
all()
如果没有连接您的模型的外键,则必须将该ON
子句作为第二个参数Query.join()
显式提供。
推荐阅读
- eclipse - 没有 CMSIS 包的 Eclipse 上的 Cortex
- android - 仅使用 Android 模块在 Android Studio 中打开 Flutter 项目
- sql - LINQ 不包含“联合”的定义
- glsl - 为什么在光线追踪器中方向是从球心到光线的原点?
- java - 尝试在空对象引用上调用虚拟方法 'android.view.SurfaceHolder android.view.SurfaceView.getHolder()'
- protractor - 当量角器脚本失败时,我们可以发送一封电子邮件,并在命令提示符中显示电子邮件内容作为错误
- java - 如何使用 Spring MVC 上传 Excel 文件?
- c - 我想将一个数组从我的主要方法传递给我的函数(min),以便可以在函数(min)中计算最小值
- c# - 时间:2019-01-10 标签:c#multiplyopeningwindowsform
- google-analytics - 使用谷歌分析创建用户个人资料