我有一张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
1条答案
按热度按时间chy5wohz1#
这也许是最好的解决办法。让我们先得到一些其他的答案。。。
是什么
EXPLAIN SELECT ...
你说呢(这也许能回答你的问题2)。您的查询将扫描整个表,而不考虑其他答案。也许你想要
LIMIT ...
最后呢?另一件可能有用的事情(取决于您的应用程序和优化器):将边界框添加到
WHERE
条款。在任何情况下,请执行以下操作以准确了解实际接触的行数:
带着这些答案回来;也许我们可以进一步迭代。
演出后状态
好,
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