У меня очень большая таблица, состоящая примерно из 3 миллионов записей в день.
Следующий запрос такой медленный
EXPLAIN SELECT *
FROM summary_by_to_days_range
WHERE(record_date BETWEEN '2019-03-12' AND '2019-03-15')
AND unit_id = 1148210
AND enum_key IN (9, 10, 38, 311)
GROUP BY unit_id, record_date
ORDER BY record_date DESC;
Со следующими результатами:
+---------+----------+-------------+---------------+---------+-----------------------------------------------------+
| rows | filtered | Extra | possible_keys | key | partitions |
+---------+----------+-------------+---------------+---------+-----------------------------------------------------+
| 9072566 | 4 | Using where | PRIMARY | PRIMARY | from20190312,from20190313,from20190314,from20190315 |
+---------+----------+-------------+---------------+---------+-----------------------------------------------------+
По сравнению с
EXPLAIN SELECT *
FROM summary_by_to_days_range
WHERE(record_date IN ('2019-03-12','2019-03-13','2019-03-14','2019-03-15'))
AND unit_id = 1148210
AND enum_key IN (9, 10, 38, 311)
GROUP BY unit_id, record_date
ORDER BY record_date DESC;
С гораздо лучшими результатами:
+------+----------+-------------+---------------+---------+-----------------------------------------------------+
| rows | filtered | Extra | possible_keys | key | partitions |
+------+----------+-------------+---------------+---------+-----------------------------------------------------+
| 16 | 100 | Using where | PRIMARY | PRIMARY | from20190312,from20190313,from20190314,from20190315 |
+------+----------+-------------+---------------+---------+-----------------------------------------------------+
И я не могу понять, почему .. Я предоставляю значения PK, единственное отличие - это предложение Between date!
Схема таблицы
`CREATE TABLE summary_by_to_days_range (
`record_date` date NOT NULL,
`unit_id` int(11) NOT NULL,
`enum_key` int(11) NOT NULL,
`str_value` varchar(200) DEFAULT NULL,
PRIMARY KEY (`record_date`,`unit_id`,`enum_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
PARTITION BY RANGE (TO_DAYS(record_date))
(PARTITION START_h VALUES LESS THAN (0) ENGINE = InnoDB,
PARTITION from20181231 VALUES LESS THAN (737425) ENGINE = InnoDB,
PARTITION from20190101 VALUES LESS THAN (737426) ENGINE = InnoDB,
.
.
PARTITION future VALUES LESS THAN MAXVALUE ENGINE = InnoDB)`
Я также пытался выполнить разбиение по ключу, по столбцу диапазона по хэшу функции DAYOFYEAR (), что привело к тому же разочаровывающему результату.
Любой