Во-первых, я признаю, что мой опыт работы с пространственными функциями очень минимален. У меня есть таблица в MySQL с 20 полями и 23549187 записей, которые содержат географические данные. Одним из полей является «точка», которая имеет тип данных точки и имеет пространственный индекс. У меня есть запрос, который выбирает все точки в многоугольнике, который выглядит так,
select * from `table_name` where ST_CONTAINS(ST_GEOMFROMTEXT('POLYGON((151.186 -23.497,151.207 -23.505,151.178 -23.496,151.174 -23.49800000000001,151.176 -23.496,151.179 -23.49500000000002,151.186 -23.497))'), `point`)
Это хорошо работает, так как многоугольник маленький. Однако, если многоугольник становится массивным, время выполнения становится очень медленным, и самый медленный запрос до сих пор выполнялся в течение 15 минут. Добавление индекса действительно помогло снизить его до 15 минут, которые в противном случае заняли бы около часа. Есть ли что-нибудь, что я могу сделать здесь для дальнейшего улучшения.
Этот запрос будет выполняться сценарием PHP, который запускается как демон, и я беспокоюсь, не вызовет ли этот медленный запрос сервер MySQL.
Приветствуются все предложения по улучшению. Спасибо.
EDIT:
show create table;
CREATE TABLE `table_name` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`lat` float(12,6) DEFAULT NULL,
`long` float(12,6) DEFAULT NULL,
`point` point NOT NULL,
PRIMARY KEY (`id`),
KEY `lat` (`lat`,`long`),
SPATIAL KEY `sp_index` (`point`)
) ENGINE=MyISAM AUTO_INCREMENT=47222773 DEFAULT CHARSET=utf8mb4
Есть еще несколько полей, которые я не должен раскрывать здесь, однако фильтр выиграл
Объяснить вывод sql для медленного запроса:
+----+-------------+------------+------+---------------+------+---------+------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+------+---------------+------+---------+------+----------+-------------+
| 1 | SIMPLE | table_name | ALL | NULL | NULL | NULL | NULL | 23549187 | Using where |
+----+-------------+------------+------+---------------+------+---------+------+----------+-------------+
Объяснить вывод sql для запроса с меньшими полигонами,
+----+-------------+------------+-------+---------------+----------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+-------+---------------+----------+---------+------+------+-------------+
| 1 | SIMPLE | table_name | range | sp_index | sp_index | 34 | NULL | 1 | Using where |
+----+-------------+------------+-------+---------------+----------+---------+------+------+-------------+
Похоже, самый большой многоугольник не использует индекс.