Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I believe that it's because MySQL doesn't support merging spatial indexes. Not sure if it's still true but I've read it somewhere in the past. If you have an OR statement, then the spatial indexes are not used</p> <p>In your case, where are you doing points.id = 1, that's a straight select with one result returned that gets used in the mbrcontains. That uses the index. </p> <p>When you add points.in (1,2,3), that returns 3 results and each needs to be mapped to the ranges table, therefore not working</p> <p>result</p> <pre><code>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 </code></pre> <p>You can simplify your test without the the point table by doing this: SELECT * FROM ranges where mbrcontains( poly, GEOMFROMWKB(POINT(0, 0)))</p> <pre><code>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 </code></pre> <p>And now this; SELECT * FROM ranges where mbrcontains( poly, GEOMFROMWKB(POINT(0, 0))) OR mbrcontains( poly, GEOMFROMWKB(POINT(10, 10)))</p> <p>result</p> <pre><code>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 </code></pre> <p>See that in the second case, you are not using index and just scanning.</p> <p>You could force the query to use index by creating UNION for each specific point but I am not sure if that's going to be faster. I did some tests locally and it was a bit slower than your first query.</p> <pre><code>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 </code></pre> <p>result</p> <pre><code>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 &lt;union1,2,3&gt; ALL NULL NULL NULL NULL NULL NULL </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload