文档章节

sql语句查询经纬度范围

渺小的尘埃
 渺小的尘埃
发布于 2013/12/04 18:31
字数 688
阅读 337
收藏 4

指定一个经纬度,给定一个范围值(单位:千米),查出在经纬度周围这个范围内的数据。

经度:113.914619

纬度:22.50128

范围:2km

longitude为数据表经度字段 latitude为数据表纬度字段

SQL在mysql下测试通过,其他数据库可能需要修改

SQL 语句如下:

<!-- lang: sql -->
select * from location where sqrt(  
(  
 ((113.914619-longitude)*PI()*12656*cos(((22.50128+latitude)/2)*PI()/180)/180)  
 *  
 ((113.914619-longitude)*PI()*12656*cos (((22.50128+latitude)/2)*PI()/180)/180)  
)  
+  
(  
 ((22.50128-latitude)*PI()*12656/180)  
 *  
 ((22.50128-latitude)*PI()*12656/180)  
)  
)<2

MySQL性能调优 – 使用更为快速的算法进行距离

最近遇到了一个问题,通过不断的尝试最终将某句原本占据近1秒的查询优化到了0.01秒,效率提高了100倍.

问题是这样的,有一张存放用户居住地点经纬度信息的MySQL数据表,表结构可以 简化为:id(int),longitude(long),latitude()long. 而业务系统中有一个功能是查找离某个用户最近的其余数个用户,通过代码分析,可以确定原先的做法基本是这样的:

$lat=20; $lon=20;//执行查询,算出该用户与所有其他用户的距离,取出最近的10个:

<!-- lang: sql -->
$sql='select * from users_location order by ACOS(SIN(('.$lat.' * 3.1415) / 180 ) *SIN((latitude * 3.1415) / 180 ) +COS(('.$lat.' * 3.1415) / 180 ) * COS((latitude * 3.1415) / 180 ) *COS(('.$lon.' * 3.1415) / 180 - (longitude * 3.1415) / 180 ) ) * 6380 asc limit 10';

而这条sql执行的速度却非常缓慢,用了近1秒的时间才返回结果,应该是因为order里的子语句用了太多的数学计算公式,导致整体的运算速度下降.

而在实际的使用中,不太可能会发生需要计算该用户与所有其他用户的距离,然后再排序的情况,当用户数量达到一个级别时,就可以在一个较小的范围里进行搜索,而非在所有用户中进行搜索.

所以对于这个例子,我增加了4个where条件,只对于经度和纬度大于或小于该用户1度(111公里)范围内的用户进行距离计算,同时对数据表中的经度和纬度两个列增加了索引来优化where语句执行时的速度.

最终的sql语句如下:

<!--lang:sql-->
$sql='select * from users_location where latitude > '.$lat.'-1 and latitude < '.$lat.'+1 and longitude > '.$lon.'-1 and longitude < '.$lon.'+1 order by ACOS(SIN(('.$lat.' * 3.1415) / 180 ) *SIN((latitude * 3.1415) / 180 ) +COS(('.$lat.' * 3.1415) / 180 ) * COS((latitude * 3.1415) / 180 ) *COS(('.$lon.'* 3.1415) / 180 - (longitude * 3.1415) / 180 ) ) * 6380 asc limit 10';

经过优化的sql大大提高了运行速度,在某些情况下甚至有100倍的提升.这种从业务角度出发,缩小sql查询范围的方法也可以适用在其他地方.

本文转载自:

渺小的尘埃
粉丝 3
博文 30
码字总数 16498
作品 0
海淀
程序员
私信 提问
lbs中从库中查询某经纬度2KM范围内的数据

sql语句查询经纬度范围 指定一个经纬度,给定一个范围值(单位:千米),查出在经纬度周围这个范围内的数据。 经度:113.914619 纬度:22.50128 范围:2km longitude为数据表经度字段 latitude为数...

laserdance
2012/02/16
0
1
geohash:用字符串实现附近地点搜索

上回说到了用经纬度范围实现附近地点搜索。 一些小型应用中这样做没问题,但在大型应用中它有个显著的缺点:速度慢。慢的原因有两个, 第一是范围比较的索引利用率并不高,第二是SQL语句极其...

jiyanle
2016/02/29
0
0
几个地理位置信息处理方案的对比和分析

对于任何LBS应用来说,让用户寻找周围的好友可能都是一个必不可少的功能,我们就以这个功能为例,来看看各种处理方案之间的差异和区别。 我们假设有如下功能需求: 显示我附近的人由近到远排...

javaer
2018/05/11
0
0
java 实现微信搜索附近人功能

最近给andorid做后台查询数据功能,有一个需求是模仿微信的查找附近人功能。 数据库中存储每个用户的经纬度信息及用户信息,通过当前用户传递过来的经纬度查询这个用户半径N公里以内的用户信...

凯文加内特
2015/09/08
333
2
geohash:用字符串实现附近地点搜索

上回说到了用经纬度范围实现附近地点搜索。 一些小型应用中这样做没问题,但在大型应用中它有个显著的缺点:速度慢。慢的原因有两个, 第一是范围比较的索引利用率并不高,第二是SQL语句极其...

leon_rock
2012/11/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

solidity智能合约如何判断地址为0或空

智能合约地址判断 在旧版本中可使用以下代码来进行比较: owner != 0x0 但如果在新版本中使用,则会提示错误信息。 那么,如何正确使用来比较地址是否为空呢。 解决方案 可以使用address(0...

程序新视界
28分钟前
3
0
RDS 5.7三节点企业版时代的数据一致性解决方案

  上篇我们看到了在MySQL主备模式下,我们在数据一致性上做了不少事情,但解决方案都有一定的局限性,适合部分场景或者解决不彻底的问题。随着以Google Spanner以及Amazon Aruora 为代表的...

阿里云官方博客
30分钟前
3
0
【百度飞浆AI Studio】1、百度飞浆AI Studio的初次使用

百度在AI人工智能方面的发力巨大,开源了优秀的PaddlePaddle平台,为开发者提供支持。 环境方面和硬件配备方面如果对于新手来说还是比较麻烦,及时使用Docker也还是对使用者有一定的门槛要求...

-个俗人
33分钟前
2
0
SaaS

什么是SaaS? SaaS(Software as a Service),即多租户(或多承租)软件应用平台. SaaS是这样一种架构模式:它让多个不同环境的用户使用同一套应用程序,且保证用户之间的数据相互隔离。 多租...

禅明
36分钟前
1
0
Nginx常用命令

#Nginx常用命令 nginx -V(大写)查看已安装的nginx安装了什么模块及其详细版本信息nginx -v查看nginx版本nginx -tnginx检查配置文件是否正确,同时显示配置文件路径nginx -c...

我爱吃炒鸡
39分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部