MySQL查询通过纬度和经度查找POI需要很长时间

MySQL查询通过纬度和经度查找POI需要很长时间,mysql,Mysql,我在MySQL表(v5.0.77)中有1700万个关注点,其中包含几个字段,包括name、lat、lng和category。Lat和Long为十进制(10,6)类型,类别为小整数。我有一个关于lat、lng和类别的多列索引 我的查询需要很长时间才能找到距离位置2公里以内的点,平均约120秒 如果我从完全相同的中心点进行查询,我可以判断查询是缓存的b/c查询在不到一秒的时间内执行。只要我更改中心点,查询就会再次花费很长时间 我进行计算是为了确定我在查询外部搜索的区域的边界,而不是查询内部的距离计算

我在MySQL表(v5.0.77)中有1700万个关注点,其中包含几个字段,包括name、lat、lng和category。Lat和Long为十进制(10,6)类型,类别为小整数。我有一个关于lat、lng和类别的多列索引

我的查询需要很长时间才能找到距离位置2公里以内的点,平均约120秒

如果我从完全相同的中心点进行查询,我可以判断查询是缓存的b/c查询在不到一秒的时间内执行。只要我更改中心点,查询就会再次花费很长时间

我进行计算是为了确定我在查询外部搜索的区域的边界,而不是查询内部的距离计算,这是您看到的许多报告的来源,这些报告都是关于花费很长时间的类似查询的

下面是慢速查询日志中的一个示例:

Query_time: 177  Lock_time: 0  Rows_sent: 2841  Rows_examined: 28691

SELECT p.id, p.name AS name, p.lat, p.lng, c.name AS category
FROM poi AS p 
LEFT JOIN categories AS c ON p.category = c.id
WHERE p.lat BETWEEN 37.524993 AND 37.560965 AND p.lng BETWEEN -77.491776 AND -77.446408; 
我觉得服务器的调优是正确的——我有足够的内存,只是我在使用它进行开发,我觉得我已经适当地调整了MySQL设置


这真的让我难堪了一段时间。MySQL不应该能够非常高效地扫描我创建的索引吗?我应该转换为空间数据类型,还是使用Sphinx来提高查询速度?任何想法/观点都值得赞赏。

这似乎有些极端,但您可以在插入、更新和检索过程中硬编码逻辑,查看
类别
字段,并选择与您要查找的
类别
类型匹配的表。是的,这意味着您将有专门针对某一类别的表,这可能对大多数人来说过于繁重,并使以后的维护变得复杂。但是,如果你的类别没有被经常修改(GPS坐标不会把我当成一个随时会发生变化的东西),你可能会考虑它。

< P>你在MySQL中尝试使用空间扩展吗?http://dev.mysql.com/doc/refman/5.1/en/spatial-extensions.html)? 我认为,如果使用日期类型“geometry”作为索引,并使用由经纬度创建的矩形进行搜索,则可以在数据库中获得更好的性能。(有关类型几何图形的信息)


我已经将它用于一个150k的数据库。放置并在几毫秒内响应查询。

包括索引和执行计划,请确定您的查询使用的是您提到的多列索引吗?请试着解释一下你的问题。我认为如果您将多列索引更改为只包含(
lat
lon
)列,并从中删除
category
,可能会有所帮助。根据类别或您认为合适的任何内容,将数据拆分为多个表也可能是有意义的,但只有在没有其他数据可用的情况下才会这样做。它正在使用索引:
id选择类型表类型可能的键键参考行额外1个简单p范围Lat,Lng,类别Lat,Lng,Category 12 NULL 23774使用where 1 SIMPLE c eq_ref PRIMARY 2 p.Category 1
@Abhay我从查询中删除了Category表上的左连接,这仍然需要很长时间。解释似乎很好,没有显示任何奇怪的地方。即使从慢速查询日志来看,您检查的行也没有那么大。我想这是进一步分析的主题。考虑到表的大小,MySQL可能会执行相当多的磁盘读写操作。请您尝试微调MySQL的一些环境变量,比如key\u buffer\u size和read\u buffer\u size。这篇文章可能会有帮助-Drograns,你的意思是按类别进行切分吗?嗯,以前从未听说过这个词。提到一个名为
表分区
的术语,它似乎符合我的想法……虽然它建议按逻辑进行分区,但这是一个更持久的方法……我并不是说这是一个坏主意,但我认为这对于开发来说是危险和昂贵的。使用像spatial i这样的阿片指数,这种情况可能更合适。坦率地说,我同意。OP声称,一个在120秒内筛选1700万条记录的查询,让我觉得有更合理的选择。但如果OPs POI继续增长,按类别划分的分片将(最终)获得回报。谢谢你给我介绍了一个新学期!你能举个例子吗?