我在MariaDB中有一个包含两个datetime
列begin
和end
的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;
然后使用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
还是我错过了什么?
答案 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坐标,并以这种方式使用空间搜索。