Ik geloof dat dit komt omdat MySQL geen ondersteuning biedt voor het samenvoegen van ruimtelijke indexen. Ik weet niet zeker of het nog steeds waar is, maar ik heb het ergens in het verleden gelezen. Als je een OR-statement hebt, worden de ruimtelijke indexen niet gebruikt
In jouw geval, waar doe je points.id =1, dat is een rechte selectie met één geretourneerd resultaat dat wordt gebruikt in de mbrcontains. Dat maakt gebruik van de index.
Wanneer u points.in (1,2,3) toevoegt, levert dat 3 resultaten op en elk moet worden toegewezen aan de bereiktabel, en werkt daarom niet
resultaat
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
U kunt uw test vereenvoudigen zonder de puntentabel door dit te doen:SELECT * FROM bereiken waar mbrbevat( 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
En nu dit; SELECTEER * FROM bereiken waar mbrbevat( poly, GEOMFROMWKB(POINT(0, 0))) OF mbrbevat( poly, GEOMFROMWKB(POINT(10, 10)))
resultaat
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
Zie dat in het tweede geval u geen index gebruikt en alleen scant.
Je zou de query kunnen dwingen om index te gebruiken door UNION te maken voor elk specifiek punt, maar ik weet niet zeker of dat sneller zal zijn. Ik heb wat tests lokaal gedaan en het was iets langzamer dan je eerste vraag.
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
resultaat
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