Выбор данных за последние 3 даты посещения (последний, предыдущий, предыдущий) - эффективность запроса - PullRequest
0 голосов
/ 22 мая 2019

Я пытаюсь вернуть GPS-координаты за последние 3 посещения магазина.Текущее посещение Предыдущее посещение До этого.

Задача состоит в том, что существует более 15 000 магазинов, каждый из которых был бы посещен в разные даты (в течение года).

Я только написалмой запрос на повторную настройку двух последних посещений (текущего и предыдущего), и я уже сталкиваюсь с проблемами эффективности, поскольку запрос выполняется вечно.

У меня есть запрос, верный набор данных, однако эффективности не хватаеточень, поскольку это занимает очень много времени для запуска (количество часов).

SELECT 
    MAX(ActionDate)     'VisitDate'
,   Store           'Store'
,   Route           'Route'
,   GPS         'GPS'
FROM 
    sys_data.mod_visit AA
WHERE 
    ActionDate  = (SELECT 
               MAX(ActionDate) FROM sys_data.mod_visit MX
               WHERE 
              ActionDate < (SELECT MAX(ActionDate) FROM sys_data.mod_visit WHERE Store = MX.Store)
               AND MX.Store = AA.Store 
                       GROUP BY 
             Store)
AND ActionDate < CURDATE()
AND YEAR(ActionDate) = YEAR(CURDATE())

Индексируются как столбцы store, так и actiondate.

Мне нужно найти способ выполнить этот выбор более эффективно, чтобы я мог использовать запрос ежедневно.

Ответы [ 2 ]

1 голос
/ 22 мая 2019

Дата действия, если is = (подзапрос), не требуется AND ActionDate

и вместо подзапроса where вы можете попробовать внутреннее соединение

    SELECT 
        MAX(ActionDate)     'VisitDate'
    ,   Store           'Store'
    ,   Route           'Route'
    ,   GPS         'GPS'
    FROM  sys_data.mod_visit AA
    INNER JOIN   (
      SELECT Store, MAX(ActionDate) max_date 
      FROM sys_data.mod_visit 
      WHERE  ActionDate < CURDATE()
      GROUP BY Store
    ) MX on MX.max_date  = AA.ActionDate 
          AND MX.store  = AA.store 
  WHERE YEAR(ActionDate) = YEAR(CURDATE())

в любом случае убедитесь, что у вас есть правильный составной индекс на

  table  sys_data.mod_visit  columns  (store , ActionDate)
0 голосов
/ 22 мая 2019

В MySQL 8 вы можете использовать оконную функцию ROW_NUMBER() для перечисления строк в Store в порядке ActionDate.Затем вы просто просматриваете первые три (для магазина):

SELECT *
FROM (
    SELECT 
        ActionDate     'VisitDate'
    ,   Store           'Store'
    ,   Route           'Route'
    ,   GPS         'GPS'
    ,   ROW_NUMBER() OVER (PARTITION BY Store ORDER BY ActionDate DESC) rn
    FROM 
        sys_data.mod_visit AA
    WHERE ActionDate < CURDATE()
      AND YEAR(ActionDate) = YEAR(CURDATE())
) x
WHERE rn <= 3

У вас должен быть составной индекс на (Store, ActionDate).Но трудно сказать, как оптимизатор использует индексы для оконных функций.

Также я бы переписал

AND YEAR(ActionDate) = YEAR(CURDATE())

на

AND ActionDate >= DATE_FORMAT(CURDATE(), '%Y-01-01')
...