Spatial Index not being used for polygon-in-bounding-box search

不羁岁月 提交于 2019-12-12 22:40:23

问题


I have a MyISAM table in MariaDB containing two datetime columns begin and end and would like to create and use a spatial index on the two in a similar fashion to the blog post here.

Here is how I create the table:

CREATE TABLE `mytable` (
  `id` int(11) NOT NULL,
  `begin` datetime NOT NULL,
  `end` datetime NOT NULL,
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4

After filling the table with data, I then add a polygon column:

ALTER TABLE mytable add time_range_int POLYGON NULL;

then fill the column with polygons created from begin and end:

UPDATE mytable
  SET time_range_int=Polygon(
    LineString(
      Point(UNIX_TIMESTAMP(begin), 1),
      Point(UNIX_TIMESTAMP(begin), 0),
      Point(UNIX_TIMESTAMP(end), 0),
      Point(UNIX_TIMESTAMP(end), 1),
      Point(UNIX_TIMESTAMP(begin), 1)
    )
  );

I then set the column to NOT NULL and create a spatial index upon it:

ALTER TABLE mytable MODIFY time_range_int POLYGON NOT NULL;
CREATE SPATIAL INDEX index_time_range on mytable(time_range_int);

Then I try to query the table for rows that contain the timespan between 2016-12-19 and 2016-12-20 which I normally do without the spatial index as follows:

SELECT SQL_NO_CACHE begin, end from mytable WHERE begin<="2016-12-19" and end>="2016-12-20";

Trying to utilize the newly created spatial index by using instead:

SELECT SQL_NO_CACHE begin, end FROM mytable
  WHERE MBRWithin(
    Polygon(
      LineString(
        Point(UNIX_TIMESTAMP("2016-12-19 00:00:00"), 1),
        Point(UNIX_TIMESTAMP("2016-12-19 00:00:00"), 0),
        Point(UNIX_TIMESTAMP("2016-12-20 00:00:00"), 0),
        Point(UNIX_TIMESTAMP("2016-12-20 00:00:00"), 1),
        Point(UNIX_TIMESTAMP("2016-12-19 00:00:00"), 1)
      )
    ),
    time_range_int,
);

(Thanks O. Jones for the hint concerning order of parameters) However, the spatial index is not being used and both versions of the query require the same execution time. Even though Explain on the second shows that the query is using the index:

+------+---------------+---------+--------+------------------+------------------+-----------+--------+--------+-------------+
|   id | select_type   | table   | type   | possible_keys    | key              |   key_len |    ref |   rows | Extra       |
|------+---------------+---------+--------+------------------+------------------+-----------+--------+--------+-------------|
|    1 | SIMPLE        | mytable | range  | index_time_range | index_time_range |        34 | <null> |  67505 | Using where |
+------+---------------+---------+--------+------------------+------------------+-----------+--------+--------+-------------+

And I notice no speed difference when I run the second query with IGNORE INDEX(index_time_range)

Is this a bug in MariaDB? My Version is 10.1.21-MariaDB or am I missing something?


回答1:


Try switching the order of parameters to MBRContains() something like this.

SELECT begin, end FROM mytable
  WHERE MBRContains(
    Polygon(
      LineString(
        Point(UNIX_TIMESTAMP("2016-12-19 00:00:00"), 1),
        Point(UNIX_TIMESTAMP("2016-12-19 00:00:00"), 0),
        Point(UNIX_TIMESTAMP("2016-12-20 00:00:00"), 0),
        Point(UNIX_TIMESTAMP("2016-12-20 00:00:00"), 1),
        Point(UNIX_TIMESTAMP("2016-12-19 00:00:00"), 1)
      )
    ),
    time_range_int);

I've had success, with actual x and y coordinates, with using the spatial search that way.



来源:https://stackoverflow.com/questions/43757499/spatial-index-not-being-used-for-polygon-in-bounding-box-search

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!