Почему этот запрос не использует ключ (пространственный MySQL 5.7)?

Я использую MySQL 5.7.10, механизм хранения — InnoDB. Ниже приведены SQL-запросы.
1. Создайте таблицу.

CREATE TABLE `geo` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`geo` GEOMETRY NOT NULL,
PRIMARY KEY (`id`),
SPATIAL INDEX `geo` (`geo`)
)
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1

2. вставить данные

insert into geo(geo) values(ST_GeomFromText('POINT(108.875000 34.216020)'));
insert into geo(geo) values(ST_GeomFromText('POINT(109.569098 36.646357)'));
insert into geo(geo) values(ST_GeomFromText('POINT(109.550988 36.633384)'));
insert into geo(geo) values(ST_GeomFromText('POINT(109.472800 36.624116)'));
insert into geo(geo) values(ST_GeomFromText('POINT(109.487460 36.563614)'));
insert into geo(geo) values(ST_GeomFromText('POINT(109.532016 36.686191)'));
insert into geo(geo) values(ST_GeomFromText('POINT(109.319010 36.987505)'));

3. создать многоугольник

SET @g3 = ST_GeomFromText('Polygon((108 36.5,108 36.7,109.5 36.7,109.5 36.5,108 36.5))');

4. объяснить SQL

mysql> explain select st_x(geo),st_y(geo) from geo where mbrcontains(@g3,geo)>0\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: geo
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 8
filtered: 100.00
Extra: Using where
1 row in set, 1 warning (0.00 sec)

mysql> show warnings\G
*************************** 1. row ***************************
Level: Note
Code: 1003
Message: /* select#1 */ select st_x(`map`.`geo`.`geo`) AS `st_x(geo)`,st_y(`map`.`geo`.`geo`) AS `st_y(geo)` from `map`.`geo` where (mbrcontains((@`g3`),`map`.`geo`.`geo`) > 0)
1 row in set (0.00 sec)

Почему этот запрос не использует ключ?


person user2400825    schedule 20.01.2016    source источник
comment
Ваш EXPLAIN вернул предупреждение. Что это было? (Запустите SHOW WARNINGS после запроса, чтобы отобразить предупреждение.)   -  person    schedule 20.01.2016
comment
mysql> show warnings\G *************************** 1. row *************************** Level: Note Code: 1003 Message: /* select#1 */ select st_x(``map.geo.geo) AS st_x(geo),st_y(map.geo.geo) AS st_y(geo) from map.geo где (mbrcontains((@g3),map.geo.geo) › 0) 1 строка в наборе (0,00 сек) `   -  person user2400825    schedule 20.01.2016
comment
Пожалуйста, включите предупреждения в свой вопрос, а не в комментарий.   -  person    schedule 20.01.2016


Ответы (2)


На основании этого Percona post

«Пространственные индексы (RTREE) поддерживаются только для таблиц MyISAM. Можно использовать функции для таблиц InnoDB, но не будут использоваться пространственные ключи»

person vmachan    schedule 20.01.2016

Сначала я хотел добавить это как комментарий к принятому ответу, но потом решил добавить еще один, поскольку принятый ответ неверен.

InnoDB поддерживает пространственные индексы в версии 5.7. Причина, по которой ваш запрос с InnoDB пропускает индекс, связана с оптимизатором, а не с отсутствием поддержки в механизме хранения. Оптимизатор просто решает, что в случае с InnoDB использование индекса невыгодно (по каким-то причинам). Чтобы подтвердить это, добавьте в таблицу дополнительные строки (в идеале со случайным распределением точек) и повторите запрос.

person matt    schedule 03.06.2019