Вярвам, че това е така, защото MySQL не поддържа обединяване на пространствени индекси. Не съм сигурен дали все още е вярно, но съм го чел някъде в миналото. Ако имате оператор ИЛИ, тогава пространствените индекси не се използват
Във вашия случай къде правите points.id =1, това е директно избиране с един върнат резултат, който се използва в mbrcontains. Това използва индекса.
Когато добавите points.in (1,2,3), това връща 3 резултата и всеки трябва да бъде съпоставен към таблицата с диапазони, следователно не работи
резултат
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE points range PRIMARY PRIMARY 4 NULL 3 100.00 Using where
1 SIMPLE ranges ALL poly NULL NULL NULL 6467418 100.00
Можете да опростите теста си без таблицата с точки, като направите следното:SELECT * FROM диапазони, където mbrcontains( poly, GEOMFROMWKB(POINT(0, 0)))
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE ranges range poly poly 34 NULL 1 100.00 Using where
А сега това; ИЗБЕРЕТЕ * ОТ диапазони, където mbrсъдържа(поли, GEOMFROMWKB(ТОЧКА(0, 0))) ИЛИ mbrсъдържа(поли, GEOMFROMWKB(ТОЧКА(10, 10)))
резултат
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE ranges ALL poly NULL NULL NULL 6467418 100.00 Using where
Вижте, че във втория случай не използвате индекс, а просто сканирате.
Можете да принудите заявката да използва индекс, като създадете UNION за всяка конкретна точка, но не съм сигурен дали това ще бъде по-бързо. Направих някои тестове на място и беше малко по-бавно от първото ви запитване.
EXPLAIN EXTENDED
SELECT *
FROM points
FORCE INDEX (PRIMARY )
LEFT JOIN ranges
FORCE INDEX ( poly ) ON mbrcontains( poly, point )
WHERE points.id = 1
UNION DISTINCT
SELECT *
FROM points
FORCE INDEX (PRIMARY )
LEFT JOIN ranges
FORCE INDEX ( poly ) ON mbrcontains( poly, point )
WHERE points.id = 2
UNION DISTINCT
SELECT *
FROM points
FORCE INDEX (PRIMARY )
LEFT JOIN ranges
FORCE INDEX ( poly ) ON mbrcontains( poly, point )
WHERE points.id = 3
резултат
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY points const PRIMARY PRIMARY 4 const 1 100.00
1 PRIMARY ranges range poly poly 34 NULL 1 100.00 Using where
2 UNION points const PRIMARY PRIMARY 4 const 1 100.00
2 UNION ranges range poly poly 34 NULL 1 100.00 Using where
3 UNION points const PRIMARY PRIMARY 4 const 1 100.00
3 UNION ranges range poly poly 34 NULL 1 100.00 Using where
NULL UNION RESULT <union1,2,3> ALL NULL NULL NULL NULL NULL NULL