为什么我的空间索引会变慢?

时间:2018-03-26 19:36:05

标签: mysql spatial

我有两张桌子

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秒

1 个答案:

答案 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