Uważam, że dzieje się tak dlatego, że MySQL nie obsługuje scalania indeksów przestrzennych. Nie jestem pewien, czy to nadal prawda, ale czytałem to gdzieś w przeszłości. Jeśli masz instrukcję OR, indeksy przestrzenne nie są używane
W twoim przypadku, gdzie robisz points.id =1, jest to prosty wybór z jednym zwróconym wynikiem, który jest używany w mbrcontains. Używa indeksu.
Po dodaniu points.in (1,2,3) zwraca 3 wyniki, a każdy z nich musi być zmapowany do tabeli zakresów, dlatego nie działa
wynik
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
Możesz uprościć test bez tabeli punktów, wykonując następujące czynności:SELECT * FROM zakresy, w których 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
A teraz to; SELECT * FROM zakresy, w których mbrcontains( poly, GEOMFROMWKB(POINT(0, 0))) OR mbrcontains( poly, GEOMFROMWKB(POINT(10, 10))))
wynik
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
Zobacz, że w drugim przypadku nie używasz indeksu i po prostu skanujesz.
Możesz zmusić zapytanie do użycia indeksu, tworząc UNION dla każdego określonego punktu, ale nie jestem pewien, czy to będzie szybsze. Zrobiłem kilka testów lokalnie i było to trochę wolniejsze niż twoje pierwsze zapytanie.
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
wynik
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