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

标签 mysql sql mariadb myisam spatial-index

我在 MariaDB 中有一个 MyISAM 表,其中包含两个 datetimebeginend 并且想在两个与 blog post here 类似的方式.

这是我创建表格的方式:

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 还是我遗漏了什么?

最佳答案

尝试将参数的顺序切换为 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 坐标,并以这种方式使用空间搜索。

关于mysql - 空间索引未用于多边形边界框搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43757499/

相关文章:

mysql - 如何在MySQL列中插入没有匹配的NULL值?

php - Doctrine 2 DBAL 中的类型映射

mysql - 两者上的 SQL JOIN

mysql - 执行查询并获取自己的pid

mysql - 从多个表中选择 - 一对多关系

mysql - MariaDB 事件流动态列?

mysql - 如何创建Mysql动态带条件查询语句

php - 单选按钮检查来自 mysql 的负载

SQL查询连接问题

sql - 保证多个FK字段属于另一个表的同一行