Jag tror att det beror på att MySQL inte stöder sammanslagning av rumsliga index. Inte säker på om det fortfarande är sant men jag har läst det någonstans tidigare. Om du har en OR-sats, används inte de rumsliga indexen
I ditt fall, var gör du points.id =1, det är ett rakt urval med ett resultat som används i mbrcontains. Som använder indexet.
När du lägger till points.in (1,2,3) returnerar det 3 resultat och varje resultat måste mappas till intervalltabellen och fungerar därför inte
resultat
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
Du kan förenkla ditt test utan punkttabellen genom att göra så här:SELECT * FROM intervall där 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
Och nu detta; SELECT * FROM intervall där mbr innehåller( poly, GEOMFROMWKB(POINT(0, 0))) ELLER mbr innehåller( poly, GEOMFROMWKB(POINT(10, 10)))
resultat
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
Se att i det andra fallet använder du inte index och bara skannar.
Du kan tvinga frågan att använda index genom att skapa UNION för varje specifik punkt men jag är inte säker på om det kommer att gå snabbare. Jag gjorde några tester lokalt och det var lite långsammare än din första fråga.
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
resultat
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