Как эффективно вернуть несколько отфильтрованных отсчетов из подзапроса - PullRequest
0 голосов
/ 01 апреля 2019

У меня есть таблица с ~ 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 млн. Строк в месяц, поэтому проблема будет только усугубляться.Любая помощь или совет очень приветствуются, большое вам спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...