Jeg tror, at det er fordi MySQL ikke understøtter fletning af rumlige indekser. Ved ikke om det stadig er sandt, men jeg har læst det et sted tidligere. Hvis du har en OR-sætning, så bruges de rumlige indekser ikke
I dit tilfælde, hvor laver du points.id =1, det er en straight select med ét resultat returneret, som bliver brugt i mbrcontains. Det bruger indekset.
Når du tilføjer points.in (1,2,3), returnerer det 3 resultater, og hver af dem skal tilknyttes rækkeviddetabellen, og virker derfor ikke
resultat
id select_type table type possible_keys key key_len ref rows filtered Extra1 SIMPLE points range PRIMÆR PRIMÆR 4 NULL 3 100,00 Bruger where1 SIMPLE områder ALLE poly NULL NULL NULL 6467418 100,00
Du kan forenkle din test uden punkttabellen ved at gøre dette:SELECT * FROM intervaller, hvor mbrcontains( poly, GEOMFROMWKB(POINT(0, 0)))
id select_type table type possible_keys key key_len ref rows filtreret Extra1 SIMPLE ranges range poly poly 34 NULL 1 100,00 Bruger hvor
Og nu dette; SELECT * FRA områder, hvor mbrcontains( poly, GEOMFROMWKB(POINT(0, 0))) OR mbrcontains( poly, GEOMFROMWKB(POINT(10, 10)))
resultat
id select_type table type possible_keys key key_len ref rows filtered Extra1 SIMPLE ranges ALL poly NULL NULL NULL 6467418 100,00 Bruger hvor
Se, at i det andet tilfælde bruger du ikke indeks og kun scanner.
Du kan tvinge forespørgslen til at bruge indeks ved at oprette UNION for hvert specifikt punkt, men jeg er ikke sikker på, om det vil være hurtigere. Jeg lavede nogle test lokalt, og det var en smule langsommere end din første forespørgsel.
EXPLAIN EXTENDED SELECT *FROM pointsFORCE INDEX (PRIMARY )LEFT JOIN rangesFORCE INDEX ( poly ) ON mbrcontains( poly, point )WHERE points.id =1UNION DISTINCTSELECT *FROM pointsFORCE INDEX (PRIMARY )FORCE JOIN EXS (PRIMARY )FORCE INDEX-intervaller ) ON mbrcontains( poly, point )WHERE points.id =2UNION DISTINCTSELECT *FROM pointsFORCE INDEX (PRIMARY )LEFT JOIN rangesFORCE INDEX ( poly ) ON mbrcontains( poly, point )WHERE points.id =3
resultat
id select_type tabeltype mulig_nøgler nøgle key_len ref rækker filtreret Ekstra1 PRIMÆR punkter const PRIMÆR PRIMÆR 4 konst 1 100,00 1 PRIMÆR områder interval poly poly 34 NULL 1 100,00 Bruger where2 UNION point const PRIMARY PRIMARY 00 UNION 1 const. interval poly poly 34 NULL 1 100,00 Bruger where3 UNION points const PRIMARY PRIMARY 4 const 1 100,00 3 UNION intervaller interval poly poly 34 NULL 1 100,00 Bruger whereNULL UNION RESULT ALL NULL NULL NULL> ALL NULL NULL