У меня есть две таблицы: одна с точками, другая с полигонами.
CREATE TABLE `points` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`point` point NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM;
CREATE TABLE `ranges` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`poly` polygon NOT NULL,
PRIMARY KEY (`id`),
SPATIAL KEY `poly` (`poly`)
) ENGINE=MyISAM;
Я хочу объединить диапазоны с точками на точках внутри полигонов. Запросы выглядят просто:
SELECT *
FROM points
LEFT JOIN ranges
ON MBRCONTAINS(poly, point)
WHERE points.id = 2;
Этот запрос работает быстро и использует индексы, часть объяснения:
таблица | тип | possible_keys | ключ | key_len диапазоны | диапазон | поли | поли | 34
Но когда я пытаюсь объединить несколько строк из таблицы точек
:
SELECT *
FROM points
LEFT JOIN ranges
ON MBRCONTAINS(poly, point)
WHERE points.id IN (1,2,3);
, все ломается:
+ ---- + ----- -------- + ------------ + ------- + --------------- + ---- ----- + --------- + ------ + -------- + ------------- + {{1} } | id | select_type | стол | тип | possible_keys | ключ | key_len | ref | строки | Дополнительно | + ---- + ------------- + ------------ + ------- + - ------------- + --------- + --------- + ------ + -------- + ------------- + | 1 | ПРОСТО | баллы | диапазон | ПЕРВИЧНЫЙ | ПЕРВИЧНЫЙ | 4 | NULL | 3 | Используя where | | 1 | ПРОСТО | диапазоны | ВСЕ | поли | NULL | NULL | NULL | 155183 | | + ---- + ------------- + ------------ + ------- + --- ------------ + --------- + --------- + ------ + -------- + - ------------ +
Добавление FORCE INDEX (poly)
не помогает.
Примеры данных для тестовых запросов (извините, только версия php, я редко использую процедуры SQL):
//points
for($i=0;$i<=500;$i++) {
$point = mt_rand();
mysql_query('INSERT INTO points (point) VALUES (POINTFROMWKB(POINT('.$point.', 0)))');
}
$qty = 20000;
$max = mt_getrandmax();
$add = $max / $qty
$end = 0;
//polys
while($end < $max) {
$start = $end;
$end = mt_rand($start, $start + $add);
mysql_query('INSERT INTO ranges (poly) VALUES (
GEOMFROMWKB(POLYGON(LINESTRING(
POINT('.$start.', -1),
POINT('.$end.', -1),
POINT('.$end.', 1),
POINT('.$start.', 1),
POINT('.$start.', -1)
)))
)');
}