标签:经纬度 NUMBER 距离 查询 半径 查找 Oracle 范围
需求:
已知一个点的经纬度,需要从表中找出以这个点为中心,半径M米范围内的所有经纬度数据。
假设现有表 TAB_LONG_LAT_DATA,字段如下:
ID INTEGER # 点序号
LONGITUDE NUMBER # 经度
LATITUDE NUMBER # 纬度
OTHERS VARCHAR2(20) # 其他信息,不一一例举
已知中心点的经纬度为(119.576051, 25.497901),求半径范围在 500M内的所有经纬度数据?
思路:
要满足需求,我们要知道2个经纬度的距离公式,当这个距离小于M米时,这点即为需要找的点。
方案一:(查询很慢)
1、建立2点的距离公式的函数:
PI,RADIUS为Π和地球半径,计算的距离单位和RADIUS单位一致,可以根据自己的需要设置。
FUNCTION FUNC_DISTANCE(lonA NUMBER, latA NUMBER, lonB NUMBER, latB NUMBER) RETURN NUMBER;
2、根据需求,直接从表中查询结果:
结果发现,在50W的数据量下,查询很慢,需要30s,甚至更高。
方案二:(超快)
1、按照方案一,建立距离函数,同时,根据距离公式,反推以中心点为中心,算出方形范围内(正方形边长=2 * 距离)最大最小经纬度的函数,
返回类型为对象表,字段信息: min_lon, max_lon, min_lat, max_lat
函数需要的对象及对象表:
同时,在原有表中对经纬度字段建立索引:
完整的函数如下:
2、先根据半径范围,把数据缩小到方形范围内的结果集,然后在结果集中计算距离符合的点,优化后的sql如下:
在调试中发现,红框中的对象表,如果不加“ where ROWNUM = 1” 条件,则查询也很慢,查看执行计划,这个对象表查询花费很多资源,但实际单独查询很快,
可能是嵌套问题,加 where条件后,只返回一行,而对象表里面实际也就一行,我们也就只需要这一行,此时执行效率就很快了,基本在1s内。
总结:
通过方案的对比,对于sql查询的where条件需要计算,且没有其他条件来走索引,只能全表扫描时,我们可以换个思路,是否可以把查询范围先缩小,然后在小范围内,再去刷选满足条件的数据,从而达到需求目的。
计算方形范围的最值算法如下:
需要用到的公式:、
具体算法:需要求方形四个角的经纬度
D为距离,R为地球半径, PI, lonA, latA 为已知中心点的经纬度
标签:经纬度,NUMBER,距离,查询,半径,查找,Oracle,范围 来源: https://www.cnblogs.com/stonets/p/16199856.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。