Ускорьте пространственный запрос MySQL (поиск точки в многоугольнике) - PullRequest
1 голос
/ 20 марта 2019

У меня есть таблица с именем cities:

CREATE TABLE `cities` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `city` varchar(255) DEFAULT NULL,
  `state_code` varchar(10) DEFAULT NULL,
  `country_code` varchar(10) DEFAULT NULL,
  `latitude` double DEFAULT NULL,
  `longitude` double DEFAULT NULL,
  `geom` geometry NOT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  KEY `country_code` (`country_code`),
  SPATIAL KEY `geom` (`geom`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Содержит около 4000 строк, ни в одной из которых не заполнено поле state_code. Я пытаюсь заполнить это поле данными из другой таблицы с именем geodata:

CREATE TABLE `geodata` (
  `region_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `country_code` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  `state_code` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  `geom` geometry NOT NULL,
  PRIMARY KEY (`region_id`),
  KEY `country_code` (`country_code`),
  KEY `state_code` (`state_code`),
  SPATIAL KEY `geom` (`geom`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Эта таблица содержит ~ 1500 строк с данными о многоугольниках для каждого из штатов США и провинций Канады (в некоторых штатах имеется более одной записи, поскольку исходные данные разбили ее на несколько геометрий).

Я пытаюсь найти наиболее эффективный запрос для поиска точки cities.geom во всех geodata.geom многоугольниках, а затем обновления cities.state_code соответствующими данными из таблицы geodata.

Так же, как тест (ВЫБОР, а не ОБНОВЛЕНИЕ), я попробовал это:

SELECT
    C.cityid_ppn,
    C.city,
    C.latitude,
    C.longitude,
    G.state_code,
    G.country_code
FROM cities C
LEFT JOIN geodata G ON (
    C.country_code = G.country_code
    AND ST_WITHIN(C.geom, G.geom)
)
WHERE
    G.country_code='CA'
    AND g.state_code='ON'
;

Даже с этим подмножеством данных запрос занимает 9 секунд. Пытаясь запустить его на полном комплекте (т. Е. Без пункта WHERE ... выше), я сдался после ожидания 5 минут.

Что я делаю не так? И как лучше всего сделать обновление cities?

...