Здравствуйте.
Не получается сократить время запроса.
Есть 3 таблицы. Контекст, запрос, точка. В контексте может быть много запросов, а в запросе может быть много точек. Самая объёмная таблица - точка.
Требуется для каждого контекста найти сумму точек. Т.е. для каждого контекста перебрать его запросы и подсчитать количество точек, принадлежащих этим запросам, и сложить.
Как дело обстоит сейчас. Ищутся все контексты и выводятся в таблицу (html), для столбца суммы точек для каждого контекста отдельно создаётся свой запрос по поиску суммы точек, что плохо сказывается на скорости. С увеличением количества точек общее время запрос (и отображения страницы) сильно увеличивается.
# Model
class Context(Model):
requests = relationship(Request, backref="context")
class Request(Model):
context_id = db.Column(db.ForeignKey('context.id'))
points = relationship('Point', backref='requests', lazy='dynamic')
class Point(Model):
request_id = db.Column(db.ForeignKey('requests.id'))
class Context(Model):
def get_point_count(self):
subquery = Request.query \
.with_entities(Request.id) \
.with_parent(self) \
.subquery()
count = Point.query \
.join(Request, Point.requests) \
.filter(Request.id.in_(subquery)) \
.distinct(Point.attr) \
.count()
return count
# View
query = Context.query
query = query.with_entities(func.max(Context.id))
query = query.group_by(Context.user_id)
subquery = query.subquery()
query = query.filter(Context.id.in_(subquery))
query = query.order_by(Context.id.desc())
contexts = query.all() # ~200ms
# в таблице отображаю контексты и для каждого контекста показываю количество точек
for ctx in contexts:
ctx.get_point_count() # ~20ms
# Если контекстов на странице 20, то соответственно к основному запросу добавляется 20 запросов, что увеличивает общее время на ~400ms
Как более правильно решить эту задачу?
Спасибо.