У меня есть 2 таблицы в базе данных MariaDB 10.3.
Примечание. Чтобы не искажать результаты, все запросы выполнялись с отключенным кешем запросов на сервере MariaDB.
- Places - Таблица содержит 2 FLOAT столбцы Lat и Lng с GPS-координатами.У меня здесь около 3.000.000 очков.
- Города - Таблица содержит список из примерно 7.000 городов, границы которых определены как POLYGON тип столбца с именем Границы .У меня также есть SPATIAL индекс указанного столбца с именем также Границы .
Я пытаюсь выполнить этот запрос SQL - пока для последних 25 записей (упорядочениевыполняется по первичному ключу, так что он работает мгновенно и не является узким местом):
SELECT Places.Id, Cities.Name
FROM Places
LEFT JOIN Cities ON ST_CONTAINS(Cities.Boundaries, POINT(Places.Lat, Places.Lon)))
ORDER BY Places.Id LIMIT 25
Этот запрос занимает на моей машине 2,7 с, что абсолютно неверно.Я попытался выполнить EXPLAIN этого запроса и вижу, что Boundaries находится в столбце возможных_ключах , но NULL в ключе столбец, что означает, что пространственный индекс полностью игнорируется.
Теперь, что я попробовал до сих пор:
- Использование FORCE INDEX Ключевое слово ничего не меняет - ключ все еще не используется
- Даже LIMIT 1 занимает 0,109 с, что линейно масштабируется до того, что 25 записей занимает
- Замена JOIN подзапросом не вносит никаких изменений - запрос принимает то жевремя
- Создание выделенного столбца POINT в Размещает таблицу с предварительно кэшированным Lat / Lon в собственном формате POINT и использует его вместо POINT () inзапрос не вносит никаких изменений
А теперь интересная часть:
Когда я заменяю POINT(Places.Lat, Places.Lon)
постоянными значениями из одного случайного места, подобного этому POINT(49.472240, 17.086672)
, он внезапно использует пространственный индекс без проблем.Даже EXPLAIN показывает, что индекс используется и этот запрос занимает 0,000 секунд!
Я хочу сказать, что выполнение этого запроса LIMIT 1 на последнем месте в базе данных занимает 0,109 секунд, а MariaDB - нет.используйте пространственный индекс, однако, когда я оставляю этот запрос как есть, просто замените Lat и Lon в функции POINT () постоянными значениями - такими же, которые находятся на последнем месте в базе данных, запрос внезапно использует индекс и занимает 0,000 сек.Результат обоих запросов одинаков.
Вопрос: Почему использование данных из столбца вместо константы не позволяет MariaDB использовать пространственный индекс?Как я могу изменить этот запрос, чтобы можно было относительно быстро соединить все 3 миллиона точек с городами, используя пространственный индекс?Я не ожидаю, что он присоединится через несколько миллисекунд, но это займет годы, когда 1 запись занимает 0,1 секунды без индекса.