Оптимизация группы по запросу - PullRequest
0 голосов
/ 12 мая 2018

У меня есть две таблицы A и B. A имеет id, startDate, endDate. B имеет id, date, count. Цель состоит в том, чтобы получить максимальное число между startDate и endDate для каждой записи в A.

select a.id, a.startDate, a.endDate, max(b.count)
from A a join B b
  on a.id=b.id
 and b.date>=a.startDate
 and b.date<=a.endDate
group By a.id, a.startDate, a.endDate;

, например

A -> (1,2016-01-01,2016-01-03)

B -> (1,2016-01-01,1), (1,2016-01-02,4), (1,2016-01-03,3), (1,2016- 01-04,2)

Результат запроса -> (1,2016-01-01,2016-01-03,4) Здесь 4 - максимум (1,4,3)

У меня есть индексы на id, startDate, endDate для таблицы A и id, date для таблицы B. Число строк в A составляет около 10 КБ, а в B - 2 миллиона. Вышеприведенный запрос занимает около 5-6 с. Кто-нибудь может предложить что-нибудь, что я мог бы попробовать?

Ответы [ 2 ]

0 голосов
/ 13 мая 2018

Попробуйте добавить эти индексы и посмотреть, какой из них полезен (используя EXPLAIN):

ALTER TABLE `A` ADD INDEX `a_idx_id_startdate_enddate` (`id`,`startDate`,`endDate`);
ALTER TABLE `B` ADD INDEX `b_idx_id_date_count` (`id`,`date`,`count`);
0 голосов
/ 12 мая 2018

Это ваш запрос:

select a.id, a.startDate, a.endDate, max(b.count)
from A a join
     B b
     on a.id = b.id and
        b.date >= a.startDate and
        b.date <= a.endDate
group By a.id, a.startDate, a.endDate;

Место для начала - индекс по b(id, date, count). Это может помочь. Однако механизм запросов все еще выполняет агрегирование по всей таблице a - и это дорого.

Часто коррелированный подзапрос работает лучше:

select a.id, a.startDate, a.endDate, 
       (select max(b.count)
        from B b
        where a.id = b.id and
              b.date >= a.startDate and
              b.date <= a.endDate
       ) as count
from A a ;

Для этого вам определенно нужен вышеупомянутый индекс.

...