У меня есть таблица с именем 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
?