У меня есть таблица с ~ 5M строками, в которой хранятся загрузки прошивки от каждого пользователя.Я пытаюсь построить график количества загрузок определенного файла прошивки за последние 30 дней.
Несмотря на то, что я могу заполнить данные, запрос к базе данных происходит медленно, так как я вызываю ее один раз для каждого результата.Я также предполагаю, что подзапрос будет быстрее «предварительно фильтровать» firmware_id
перед выполнением COUNT
в каждый соответствующий день.
Определение model.py:
class Client(db.Model):
__tablename__ = 'clients'
id = Column(Integer, primary_key=True, nullable=False, unique=True)
datestr = Column(Integer, default=0, index=True)
firmware_id = Column(Integer, ForeignKey('firmware.firmware_id'), nullable=False, index=True)
datestr
- это целое число с текущим ггггммдд, например, 20190101.
В настоящее время я делаю это так:
data = []
now = datetime.date.today()
for _ in range(30):
datestr = _get_datestr_from_datetime(now)
total = _execute_count_star(db.session.query(Client).\
filter(Client.firmware_id == fw.firmware_id).\
filter(Client.datestr == datestr))
data.append(int(total))
now -= datetime.timedelta(days=1)
, где определено _execute_count_star
(на первый взгляднамного быстрее, чем .count()
) как:
def _execute_count_star(q):
count_query = q.statement.with_only_columns([func.count()]).order_by(None)
return q.session.execute(count_query).scalar()
В идеале я хотел бы вернуть все результаты за 30 дней в одном запросе (используя подзапрос для фильтрации по firmware_id
?);в настоящий момент для заполнения данных требуется около 3 с, что по умолчанию слишком много для показа пользователям.Кроме того, ожидается, что таблица будет расти на 0,5 млн. Строк в месяц, поэтому проблема будет только усугубляться.Любая помощь или совет очень приветствуются, большое вам спасибо.