Пространственный индекс не используется при некоторых обстоятельствах - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть 2 таблицы в базе данных MariaDB 10.3.

Примечание. Чтобы не искажать результаты, все запросы выполнялись с отключенным кешем запросов на сервере MariaDB.

  1. Places - Таблица содержит 2 FLOAT столбцы Lat и Lng с GPS-координатами.У меня здесь около 3.000.000 очков.
  2. Города - Таблица содержит список из примерно 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 в ключе столбец, что означает, что пространственный индекс полностью игнорируется.

Теперь, что я попробовал до сих пор:

  1. Использование FORCE INDEX Ключевое слово ничего не меняет - ключ все еще не используется
  2. Даже LIMIT 1 занимает 0,109 с, что линейно масштабируется до того, что 25 записей занимает
  3. Замена JOIN подзапросом не вносит никаких изменений - запрос принимает то жевремя
  4. Создание выделенного столбца 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 секунды без индекса.

...