MySQL - 如何使用地理位置数据加快搜索速度?

Posted

技术标签:

【中文标题】MySQL - 如何使用地理位置数据加快搜索速度?【英文标题】:MySQL - How to speed up search with using geolocation data? 【发布时间】:2014-12-15 21:55:29 【问题描述】:

我有一张带有cars 的桌子,我正在尝试查找半径范围内城市中的所有汽车。这是我用于此的查询:

SELECT cars.*,
 69.0 * HAVERSINE(cars.latitude,cars.longitude, 32.7802618, -96.80097810000001) AS distance
FROM cars
WHERE cars.latitude BETWEEN 32.7802618 - (100.0 / 69.0)
 AND 32.7802618 + (100.0 / 69.0)
 AND cars.longitude BETWEEN -96.80097810000001 - (100.0 / (69.0 * COS(RADIANS(32.7802618))))
 AND -96.80097810000001 + (100.0 / (69.0 * COS(RADIANS(32.7802618))))
 AND cars.pick_up_available = 0
ORDER BY distances

我正在测试这个查询,但它似乎可以正常工作(它会根据经纬度坐标找到距离城市 100 英里半径范围内的汽车)。但是,有一个缺点 - 查询很慢。表中有 300,000 条记录,当我运行此查询时,它返回 5,400 条记录,耗时 4.5 秒。

我尝试通过添加索引来加快速度,如下所示: CREATE INDEX idx_latitude_longitude ON cars (latitude, longitude),但没有帮助(需要 4.5 秒)。

    show index from cars;
        +----------+------------+------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
        | Table  | Non_unique | Key_name               | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
        +----------+------------+------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
        | cars   |          0 | PRIMARY                |            1 | id          | A         |      253096 |     NULL | NULL   |      | BTREE      |         |               |
        | cars   |          1 | idx_latitude_longitude |            1 | latitude    | A         |       84365 |     NULL | NULL   | YES  | BTREE      |         |               |
        | cars   |          1 | idx_latitude_longitude |            2 | longitude   | A         |       84365 |     NULL | NULL   | YES  | BTREE      |         |               |

        3 rows in set (0.13 sec)

提前谢谢你们。

【问题讨论】:

【参考方案1】:
SELECT cars.*,
 69.0 * HAVERSINE(cars.latitude,cars.longitude, 32.7802618, -96.80097810000001) AS distance
FROM cars
WHERE cars.pick_up_available = 0
 AND 32.7802618 + (100.0 / 69.0)
 AND cars.longitude BETWEEN -96.80097810000001 - (100.0 / (69.0 * COS(RADIANS(32.7802618))))
 AND -96.80097810000001 + (100.0 / (69.0 * COS(RADIANS(32.7802618))))
 AND cars.latitude BETWEEN 32.7802618 - (100.0 / 69.0)
ORDER BY distances

变化不大,但对数据的数学运算有限。

【讨论】:

【参考方案2】:

查询缓慢有很多原因。不使用索引,排序开销,错误的表结构...... 我猜您的查询不能使用索引或排序开销太大。但这只是我的猜测。 你能显示'解释选择'和'SET PROFILING = 1;询问;显示个人资料;'结果?

【讨论】:

以上是关于MySQL - 如何使用地理位置数据加快搜索速度?的主要内容,如果未能解决你的问题,请参考以下文章

具有 10+ 百万行的 MySQL 表 - 如何使用索引加快搜索速度?

如何通过 IP 地址查询加快国家检测速度?

索引如何加快搜索速度? [复制]

如何加快 WordPress 中的 GEO 搜索

如何使用 NSPredicate 加快数组搜索速度?

mysql 如何提高批量导入的速度