我在 MariaDB 中有一个 MyISAM 表,其中包含两个 datetime
列 begin
和 end
并且想在两个与 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;
然后用从 begin
和 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)
)
);
然后我将该列设置为 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-19
和 2016-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/