我有两张桌子
CREATE TABLE `city_landmark` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`location` geometry NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`),
SPATIAL KEY `spatial_index1` (`location`)
) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=latin1
CREATE TABLE `device_locations` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`location` geometry NOT NULL,
PRIMARY KEY (`id`),
SPATIAL KEY `spatial_index_2` (`location`)
) ENGINE=InnoDB AUTO_INCREMENT=1000004 DEFAULT CHARSET=latin1
城市地标行:10000
设备位置行:1000002
我想找出' device_locations'中的行数。距离每个城市地标都有一定的距离。
SELECT *,
ifnull(
(
SELECT 1
FROM city_landmark cl force INDEX (spatial_index1)
where st_within(cl.location, st_buffer(dl.location, 1, st_buffer_strategy('point_circle', 6)) ) limit 1), 0) 'in_range'
FROM device_locations dl
LIMIT 200;
由于某种原因,这真的很慢。请建议更好的方法?
由于某些原因,如果使用spatial_index1则没有区别
索引:2.067秒
没有索引:2.016秒
答案 0 :(得分:1)
我不熟悉mysql空间,我使用postgresql和postgis。但我会推测一点点。
我猜是因为您必须计算st_buffer
您无法获得索引的好处。当您执行某些功能并更改索引字段时,常规索引也是如此。
因此,如果您的城市位置是点几何,请添加另一个字段city_perimeter
并使用st_buffer
的结果填充它然后您可以为city_perimeter
创建空间索引。
您的查询应该变为:
SELECT c.id, count(*)
FROM city_landmark c
JOIN device_locations d
ON st_within(c.city_perimeter, d.location)
GROUP BY c.id