MySQL查询需要很长时间才能按纬度和经度查找POI

时间:2011-12-10 16:03:59

标签: mysql

我在MySQL表(v5.0.77)中有1700万个兴趣点,有几个字段,包括name,lat,lng和category。 Lat和Long的类型为Decimal(10,6),Category是小整数。我在lat,lng,category上有一个多列索引。

我在2公里范围内寻找点的查询需要很长时间 - 平均约120秒。

如果我从完全相同的中心点查询,我可以告诉查询缓存b / c查询在不到秒的时间内执行。一旦我更改了中心点,查询就会花费很长时间。

我进行计算以确定我在查询之外搜索的区域的边界,而不是其中的距离计算,这是您看到类似查询需要很长时间的大量报告的来源。 / p>

以下是慢查询日志中的示例:

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来提高查询速度?任何想法/观点都非常赞赏。

2 个答案:

答案 0 :(得分:1)

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

我在150k的数据库中使用过它。地点和查询在几毫秒内响应。

答案 1 :(得分:0)

这可能看起来很极端,但您可以在插入,更新和检索过程中硬编码逻辑以查看category字段,并选择与您正在查找的category类型匹配的表对于。是的,这意味着您将拥有专门针对特定类别的表格,对于大多数人而言,这可能会过于繁重,并且以后会使维护变得复杂。但是,如果您的类别不经常修改(GPS坐标不会让我觉得很快会发生变化),您可能需要考虑它。