Как ускорить Группирование по запросу

0

У меня есть запрос mysql, который занимает 30 секунд. в таблице содержится более 3 миллионов строк

вот структура db:

text (VARCHAR(64)), 
kpi1 (INT), 
kpi2 (INT), 
position (DECIMAL),
date(DATE)
device (VARCHAR(32))

Вот запрос:

select date, sum(kpi1), sum(kpi2) FROM  'table_name' GROUP BY date ;

Объяснить метод дает мне этот результат:

ID  | select type   | table        | partitions | type  | possible_keys  | key  | key_len | ref  | rows    | filtred | extra
1   | SIMPLE        | table_name   | NULL       | index | UNIQUE,DATE    | DATE | 3       | NULL | 3316480 | 100.00  | NULL

У меня есть указатель на дату.

Здесь результат с профилированием:

mysql> show profile for query 1;
+----------------------+-----------+
| Status               | Duration  |
+----------------------+-----------+
| starting             |  0.000080 |
| checking permissions |  0.000011 |
| Opening tables       |  0.000021 |
| init                 |  0.000023 |
| System lock          |  0.000011 |
| optimizing           |  0.000007 |
| statistics           |  0.000021 |
| preparing            |  0.000019 |
| Sorting result       |  0.000007 |
| executing            |  0.000005 |
| Sending data         | 32.814836 |
| end                  |  0.000011 |
| query end            |  0.000009 |
| closing tables       |  0.000009 |
| freeing items        |  0.000082 |
| cleaning up          |  0.000013 |
+----------------------+-----------+
16 rows in set, 1 warning (0,00 sec)

Любая идея?

  • 1
    Для запроса нужен индекс (date, kpi1, kpi2)
  • 0
    @NB после группировки не возвращает много строк. только 345 возвращены
Показать ещё 4 комментария
Теги:
group-by

1 ответ

1

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

insert into MyDailySummaryTable 
   ( Date, kpi1Sum, kpi2Sum, numRecs )
   select date, 
          sum(kpi1) kpi1Sum, 
          sum(kpi2) kpi2Sum,
          count(*) numRecs
      FROM  
         'table_name' 
      where
         date < curdate()
      GROUP BY 
         date ;

затем на каждый день после начальной загрузки

insert into MyDailySummaryTable 
   ( Date, kpi1Sum, kpi2Sum, numRecs )
   select date, 
          sum(kpi1) kpi1Sum, 
          sum(kpi2) kpi2Sum,
          count(*) numRecs
      FROM  
         'table_name' 
      where
         date = date_add( curdate(), interval -1 day )
      GROUP BY 
         date ;

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

Затем, пытаясь запустить ваши итоги, вы можете просто запросить у MyDailySummaryTable напрямую и получить мгновенные результаты.

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

  • 0
    спасибо за ваше решение, я имел в виду, но думаю, что-то не так с моим запросом или конфигурацией. если ничего не случилось, я буду применять это решение.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню