Добрый день!
Достаточно частая задача выборка последних данных по однму для каждого из группировки.
Например последние сообщения диалогов в каком-нибудь мессенджере.
У нас не мессенджер, но суть похожа...
Есть таблица:
CREATE TABLE `history` (
`u` int(11) NOT NULL,
`user` int(11) NOT NULL,
`gu` int(11) NOT NULL,
`lat` double NOT NULL,
`lon` double NOT NULL,
`speed` float NOT NULL,
`altitude` int(11) NOT NULL,
`time` datetime NOT NULL
) ENGINE=Aria DEFAULT CHARSET=utf8 PACK_KEYS=1;
ALTER TABLE `history`
ADD PRIMARY KEY (`u`),
ADD KEY `user_time` (`user`,`time`) USING BTREE,
ADD KEY `user_gu` (`user`,`time`,`gu`) USING BTREE,
ADD KEY `gu_time` (`gu`,`time`) USING BTREE;
Гуглением был составлен такой запрос:
SELECT t2.* FROM ( SELECT `gu`, max(`time`) AS `time` FROM `history` WHERE `user` = 123 AND `time` > NOW() - INTERVAL 30 MINUTE GROUP BY `gu` ) t1 JOIN `history` t2 USING(gu,time) ORDER BY t1.time DESC
Его EXPLAIN:
+---+---+---+---+---+---+---+---+---+---+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+---+---+---+---+---+---+---+---+---+---+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 2 | Using where; Using filesort |
| 1 | PRIMARY | t2 | ref | gu_time | gu_time | 12 | t1.gu,t1.time | 1 | |
| 2 | DERIVED | history | range | user_time,user_gu | user_time | 12 | NULL | 1 | Using index condition; Using temporary; Using filesort |
+---+---+---+---+---+---+---+---+---+---+
Вопрос такой - можно ли как-то лучше это сделать? В частности оптимизировать индексы или что-то изменить? Иногда запрос подтормаживает...
Таблица в несколько миллионов записей, растёт как на дрожжах, есть мысль разнести её на две текущую и историческу., так чтобы в той к которой этот запрос оставались только данные за последние сутки (на уровне приложения интервал не может быть больше суток).
PS индекс user_time я предвижу что избыточен, но user_gu был добавлен позднее для тестов. Потому решил пока оставить оба.
PS PS используется MariaDB 10.1
PS PS PS читал
http://sqlinfo.ru/articles/info/18.html , но не понял что мне лучше подойдёт
Отредактированно Proger (26.10.2015 14:32:14)