使用in_()方法后,Sqlalchemy查询非常慢

时间:2019-03-27 06:17:26

标签: python sqlalchemy

false

domain_name为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() 时,查询时间为3到4秒,否则为5分钟。我试图将索引添加到列,但无济于事。可能是什么原因?

1 个答案:

答案 0 :(得分:2)

domain_name不是'all'时,您最终会在CROSS JOINFlow之间执行隐式Bandwidth。将IN谓词添加到过滤器列表时,SQLAlchemy还将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()的第二个参数。