我在 MySQL 表 (v5.0.77) 中有 1700 万个兴趣点,其中包含多个字段,包括名称、纬度、经度和类别。 Lat 和 Long 的类型为 Decimal(10,6),Category 为小整数。我在 lat、lng、category 上有一个多列索引。
我查询查找位置 2 公里以内的点需要很长时间 - 平均大约 120 秒。
如果我从完全相同的中心点进行查询,我可以知道该查询已被缓存,因为查询执行时间不到一秒。一旦我改变中心点,查询又需要很长时间。
我进行计算以确定我在查询之外搜索的区域的边界,而不是在其中进行距离计算,这是您看到的许多关于花费很长时间的类似查询的报告的来源。
以下是慢查询日志中的示例:
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 来提高查询速度?非常感谢任何想法/观点。
最佳答案
您是否尝试过在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 的数据库一起使用。地点和查询在几毫秒内响应。
关于MySQL查询通过纬度和经度查找POI需要很长时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8457836/