sql >> Databasteknik >  >> RDS >> Mysql

Går med på rumsliga mysql-index

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     


  1. Hur konverterar man tidsstämpel till datetime i MySQL?

  2. SQL Uppdatera Maria DB med förberett uttalande

  3. Skapa rullgardinslista från värde i databasen php

  4. Att välja innehållet i tabellen, vilket är ett resultat av ett annat värde