Ich glaube, das liegt daran, dass MySQL das Zusammenführen räumlicher Indizes nicht unterstützt. Ich bin mir nicht sicher, ob es noch stimmt, aber ich habe es irgendwo in der Vergangenheit gelesen. Wenn Sie eine ODER-Anweisung haben, werden die räumlichen Indizes nicht verwendet
In Ihrem Fall, wo Sie Punkte machen.id =1, das ist eine direkte Auswahl mit einem zurückgegebenen Ergebnis, das in den mbrcontains verwendet wird. Das verwendet den Index.
Wenn Sie points.in (1,2,3) hinzufügen, gibt das 3 Ergebnisse zurück und jedes muss der Bereichstabelle zugeordnet werden, daher funktioniert es nicht
Ergebnis
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
Sie können Ihren Test ohne die Punktetabelle vereinfachen, indem Sie Folgendes tun:SELECT * FROM ranges where 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
Und jetzt das; SELECT * FROM ranges where mbrcontains( poly, GEOMFROMWKB(POINT(0, 0))) OR mbrcontains( poly, GEOMFROMWKB(POINT(10, 10)))
Ergebnis
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
Beachten Sie, dass Sie im zweiten Fall keinen Index verwenden und nur scannen.
Sie könnten die Abfrage zwingen, den Index zu verwenden, indem Sie UNION für jeden bestimmten Punkt erstellen, aber ich bin mir nicht sicher, ob das schneller sein wird. Ich habe einige Tests lokal durchgeführt und es war etwas langsamer als Ihre erste Abfrage.
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
Ergebnis
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