Credo che sia perché MySQL non supporta l'unione di indici spaziali. Non sono sicuro che sia ancora vero, ma l'ho letto da qualche parte in passato. Se hai un'istruzione OR, gli indici spaziali non vengono utilizzati
Nel tuo caso, dove stai facendo points.id =1, questa è una selezione diretta con un risultato restituito che viene utilizzato in mbrcontains. Che usa l'indice.
Quando aggiungi punti.in (1,2,3), restituisce 3 risultati e ciascuno deve essere mappato sulla tabella degli intervalli, quindi non funziona
risultato
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
Puoi semplificare il tuo test senza la tabella dei punti in questo modo:SELECT * FROM intervalli in cui 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
E ora questo; SELECT * FROM intervalli in cui mbrcontains( poly, GEOMFROMWKB(POINT(0, 0))) O mbrcontains( poly, GEOMFROMWKB(POINT(10, 10)))
risultato
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
Vedi che nel secondo caso, non stai usando l'indice e stai solo scansionando.
Potresti forzare la query a utilizzare l'indice creando UNION per ogni punto specifico, ma non sono sicuro che sarà più veloce. Ho eseguito alcuni test in locale ed è stato un po' più lento della tua prima query.
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
risultato
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