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分钟。我试图将索引添加到列,但无济于事。可能是什么原因?
答案 0 :(得分:2)
当domain_name
不是'all'
时,您最终会在CROSS JOIN
和Flow
之间执行隐式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()
的第二个参数。