У нас есть большая таблица со следующей структурой таблицы:Оптимизация SQL запросы от большого стола Заказанного Timestamp
CREATE TABLE `location_data` (
`id` int(20) NOT NULL AUTO_INCREMENT,
`dt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`device_sn` char(30) NOT NULL,
`data` char(20) NOT NULL,
`gps_date` datetime NOT NULL,
`lat` double(30,10) DEFAULT NULL,
`lng` double(30,10) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `dt` (`dt`),
KEY `data` (`data`),
KEY `device_sn` (`device_sn`,`data`,`dt`),
KEY `device_sn_2` (`device_sn`,`dt`)
) ENGINE=MyISAM AUTO_INCREMENT=721453698 DEFAULT CHARSET=latin1
Много раз мы выполнили запрос, такие как следующие:
SELECT * FROM location_data WHERE device_sn = 'XXX' AND data = 'location' ORDER BY dt DESC LIMIT 1;
ИЛИ
SELECT * FROM location_data WHERE device_sn = 'XXX' AND data = 'location' AND dt >= '2014-01-01 00:00:00 ' AND dt <= '2014-01-01 23:00:00' ORDER BY dt DESC;
Мы оптимизируя это несколькими способами:
- С помощью добавления индекса и использования
FORCE INDEX
наdevice_sn
. - Разделение таблицы на несколько таблиц на основе даты (например,
location_data_20140101
) и предварительная проверка наличия данных на определенную дату, и мы потянем эту конкретную таблицу отдельно. Эта таблица создается cron один раз в день, и данные вlocation_data
для этой конкретной даты будут удалены.
Таблица location_data
HIGH WRITE и LOW READ.
Однако несколько раз запрос работает очень медленно. Интересно, существуют ли другие методы/способы/реструктуризация данных, которые позволяют нам читать данные в последовательном порядке даты на основе заданного device_sn
.
Любые советы более чем приветствуются.
EXPLAIN ЗАЯВЛЕНИЕ 1ST QUERY:
+----+-------------+--------------+------+----------------------------+-----------+---------+-------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------+------+----------------------------+-----------+---------+-------------+------+-------------+
| 1 | SIMPLE | location_dat | ref | data,device_sn,device_sn_2 | device_sn | 50 | const,const | 1 | Using where |
+----+-------------+--------------+------+----------------------------+-----------+---------+-------------+------+-------------+
EXPLAIN ЗАЯВЛЕНИЕ 2-й QUERY:
+----+-------------+--------------+-------+-------------------------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------+-------+-------------------------------+------+---------+------+------+-------------+
| 1 | SIMPLE | test_udp_new | range | dt,data,device_sn,device_sn_2 | dt | 4 | NULL | 1 | Using where |
+----+-------------+--------------+-------+-------------------------------+------+---------+------+------+-------------+
'int (20)' for PK не имеет смысла. Индексы с низкой мощностью не имеют никакого смысла. В комплект поставки не входит «EXPLAIN». Вы также используете MyISAM, и если это высокая запись, сомнительно, насколько хорошо он работает (вы не можете даже контролировать огромные сбросы на диск из-за движка). Принуждение индекса с низкой мощностью не имеет смысла. MySQL использует индексы только тогда, когда он быстрее, чем необходимость полного сканирования таблицы. Теперь, если вы можете включить вывод EXPLAIN, это поможет нам проанализировать все, что не так. –
Ваши индексы отлично выглядят для запросов. Возможно, загрузка запроса/блокировка записей иногда мешает запросу. –
@ N.B. Я отредактировал свой вопрос, чтобы включить вывод инструкции EXPLAIN. Можете ли вы объяснить, почему индексы с низкой мощностью не имеют смысла? И почему заставить индекс с низкой мощностью не имеет никакого смысла? Спасибо за вашу помощь! –