Věřím, že je to proto, že MySQL nepodporuje slučování prostorových indexů. Nejsem si jistý, jestli je to stále pravda, ale někde jsem to v minulosti četl. Pokud máte příkaz OR, pak se prostorové indexy nepoužívají
Ve vašem případě, kde děláte points.id =1, je to přímý výběr s jedním vráceným výsledkem, který se použije v mbrcontains. To používá index.
Když přidáte points.in (1,2,3), vrátí to 3 výsledky a každý musí být namapován do tabulky rozsahů, proto nefunguje
výsledek
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
Svůj test bez tabulky bodů můžete zjednodušit takto:SELECT * FROM rozsahy, kde 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 teď tohle; SELECT * FROM rozsahy, kde mbrcontains( poly, GEOMFROMWKB(POINT(0, 0))) NEBO mbrcontains( poly, GEOMFROMWKB(POINT(10, 10)))
výsledek
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
Podívejte se, že ve druhém případě nepoužíváte index a pouze skenujete.
Můžete donutit dotaz použít index vytvořením UNION pro každý konkrétní bod, ale nejsem si jistý, zda to bude rychlejší. Provedl jsem nějaké testy lokálně a bylo to trochu pomalejší než váš první dotaz.
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
výsledek
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