Я строю систему IoT для бытовой техники.Как решить проблему с производительностью GROUP BY в MySQL?
Моя таблица данных была создана как
mysql> SHOW CREATE TABLE DataM1\G
*************************** 1. row ***************************
Table: DataM1
Create Table: CREATE TABLE `DataM1` (
`sensor_type` text,
`sensor_name` text,
`timestamp` datetime DEFAULT NULL,
`data_type` text,
`massimo` float DEFAULT NULL,
`minimo` float DEFAULT NULL,
KEY `timestamp_id` (`timestamp`) USING BTREE,
KEY `super_index_id` (`timestamp`,`sensor_name`(11),`data_type`(11)) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
и запрос
SELECT
sensor_type, sensor_name, timestamp, data_type,
MAX(massimo) as massimo, MIN(minimo) as minimo
FROM DataM1
WHERE timestamp >= NOW() - INTERVAL 1 HOUR
GROUP BY timestamp, sensor_type, sensor_name, data_type;
Теперь проблема в том, что, когда таблица достигает 4 миллионов (несколько дней) строки запроса занимает 50 + секунды.
Редактировать: РАЗЪЯСНЯЕМ результат заключается в следующем:
id: 1
select_type: SIMPLE
table: DataM1
partitions: p0,p1,p2,p3,p4,p5,p6
type: range
possible_keys: timestamp_id,super_index_id
key: timestamp_id
key_len: 6
ref: NULL
rows: 1
filtered: 100.00
Extra: Using index condition; Using temporary; Using filesort
Edit: образец строка ответа является:
*************************** 418037. row ***************************
sensor_type: SEN
sensor_name: SEN_N2
timestamp: 2016-10-16 17:28:48
data_type: flow_rate
massimo: 17533.8
minimo: 17533.5
Изменить: Я нормализовал значения временной метки, SENSOR_TYPE, sensor_name и DATA_TYPE и создал _view для облегчения потребления данных:
CREATE VIEW `_view` AS (
select (
select `vtmp`.`timestamp` from `timestamp` `vtmp` where (`vtmp`.`no` = `pm`.`timestamp`)) AS `timestamp`,(
select `vtmp`.`sensor_type` from `sensor_type` `vtmp` where (`vtmp`.`no` = `pm`.`sensor_type`)) AS `sensor_type`,(
select `vtmp`.`sensor_name` from `sensor_name` `vtmp` where (`vtmp`.`no` = `pm`.`sensor_name`)) AS `sensor_name`,(
select `vtmp`.`data_type` from `data_type` `vtmp` where (`vtmp`.`no` = `pm`.`data_type`)) AS `data_type`,
`pm`.`massimo` AS `massimo`,
`pm`.`minimo` AS `minimo`
from `datam1` `pm` order by `pm`.`timestamp` desc);
Есть ли способ sp с индексированием, окантовкой и/или разбиением? Или лучше пересмотреть таблицу, разделяющую информацию в разных таблицах? Если да, может ли кто-нибудь предложить свою лучшую практику в такой ситуации?
Вы должны опубликовать результат EXPLAIN. Некоторые другие данные, такие как количество строк за последний час, также будут полезны. И, может быть, некоторые образцы данных (всего несколько строк), чтобы увидеть, как выглядят ваши данные. –
@PaulSpiegel здесь является EXPLAIN результат: ID: 1 SELECT_TYPE: SIMPLE стол: DataM1 перегородки: p0, p1, p2, p3, p4, p5, p6 Тип: Диапазон possible_keys: timestamp_id, super_index_id ключ: timestamp_id key_len: 6 ref: NULL строки: 1 отфильтрован: 100,00 Дополнительно: с использованием условия индекса; Использование временных; Использование filesort – sfiore
@PaulSpiegel количество строк за последний час составляет 60 минут * 60 секунд * 8 датчиков * 4 типа данных = 115,200 – sfiore