空间索引未用于多边形边界框搜索

时间:2017-05-03 10:29:14

标签: mysql sql mariadb myisam spatial-index

我在MariaDB中有一个包含两个datetimebeginend的MyISAM表,并希望以与{{{{}}类似的方式在二者上创建和使用空间索引。 3}}

以下是我创建表格的方法:

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

在用数据填充表格之后,我添加了polygon列:

ALTER TABLE mytable add time_range_int POLYGON NULL;

然后使用beginend创建的多边形填充列:

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)
    )
  );

然后我将列设置为NOT NULL并在其上创建空间索引:

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

然后我尝试在表中查询包含2016-12-192016-12-20之间的时间跨度的行,我通常不使用空间索引,如下所示:

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

尝试使用新创建的空间索引:

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,
);

(感谢O. Jones关于参数顺序的提示) 但是,未使用空间索引,并且查询的两个版本都需要相同的执行时间。即使第二个Explain显示查询正在使用索引:

+------+---------------+---------+--------+------------------+------------------+-----------+--------+--------+-------------+
|   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 |
+------+---------------+---------+--------+------------------+------------------+-----------+--------+--------+-------------+

当我使用IGNORE INDEX(index_time_range)

运行第二个查询时,我发现没有速度差异

这是MariaDB中的错误吗?我的版本是10.1.21-MariaDB还是我错过了什么?

1 个答案:

答案 0 :(得分:1)

尝试将参数顺序切换为MBRContains()之类的内容。

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);

我已经成功地使用了实际的x和y坐标,并以这种方式使用空间搜索。