在mysql 8中使用point数据类型和st_distance_sphere查找最近的位置

3yhwsihp  于 2021-06-20  发布在  Mysql
关注(0)|答案(1)|浏览(603)

我有一张table叫 place :

id | name       | coordinates (longitude, latitude)
1  | London     | -0.12574, 51.50853
2  | Manchester | -2.25, 53.41667
3  | Glasgow    | -4.25, 55.86667

这个 coordinates 列属于点数据类型。我把这些点插入 place 表格使用:

st_geomfromtext('point($longitude $latitude)', 4326)

注意,我已经使用了srid。
给定任何坐标,我想找到离它最近的地方(按升序排列)。我目前提出的解决方案(通过阅读mysql文档)如下所示:

select
    *,
    st_distance_sphere(`place`.`coordinates`, st_geomfromtext('Point($longitude $latitude)', 4326)) as distance
from place
order by distance asc;

在这里和其他地方看了无数类似的问题之后,很明显,这是一种鲜为人知的(更新的)做事方式,所以这方面没有太多内容,因此我想澄清一下。
我的问题是:
这是最好的解决方案吗/我做得对吗?
这个方法会利用我在Map上的空间索引吗 coordinates 列?
当使用st_distance_sphere时,是否需要指定地球的半径以获得准确的结果(编辑:否,默认使用地球半径)
编辑,以下是答案: explain select ...; 退货:

id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra
1  | SIMPLE      | place | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 115687 | 100.00   | Using filesort
``` `flush status; select ...; show session status like 'Handler%';` 退货:

Variable_name | Value
Handler_commit | 1
Handler_delete | 0
Handler_discover | 0
Handler_external_lock | 2
Handler_mrr_init | 0
Handler_prepare | 0
Handler_read_first | 1
Handler_read_key | 1001
Handler_read_last | 0
Handler_read_next | 0
Handler_read_prev | 0
Handler_read_rnd | 1000
Handler_read_rnd_next | 119395
Handler_rollback | 0
Handler_savepoint | 0
Handler_savepoint_rollback | 0
Handler_update | 0
Handler_write | 0

chy5wohz

chy5wohz1#

这也许是最好的解决办法。让我们先得到一些其他的答案。。。
是什么 EXPLAIN SELECT ... 你说呢(这也许能回答你的问题2)。
您的查询将扫描整个表,而不考虑其他答案。也许你想要 LIMIT ... 最后呢?
另一件可能有用的事情(取决于您的应用程序和优化器):将边界框添加到 WHERE 条款。
在任何情况下,请执行以下操作以准确了解实际接触的行数:

FLUSH STATUS;
SELECT ...;
SHOW SESSION STATUS LIKE 'Handler%';

带着这些答案回来;也许我们可以进一步迭代。
演出后状态
好, Handler_read_rnd_next 说是全表扫描。1000和1001——你有吗 LIMIT 1000 ?
我推断 LIMIT 没有考虑到 SPATIAL 作品。也就是说,它做了一件非常简单的事情——(1)检查所有行,(2)排序,(3) LIMIT .
那么,该怎么办?
方案a:确定不希望结果超过x英里(km),并在查询中添加“边界框”。
方案b:放弃空间,挖掘更复杂的方法来完成任务:http://mysql.rjweb.org/doc.php/latlng

相关问题