需求:

  已知一个点的经纬度,需要从表中找出以这个点为中心,半径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 为已知中心点的经纬度

    

Oracle中查找某个点半径范围内的所有经纬度(优化)的更多相关文章

  1. oracle中查找和删除重复记录的几种方法总结

    平时工作中可能会遇到当试图对库表中的某一列或几列创建唯一索引时,系统提示 ORA-01452 :不能创建唯一索引,发现重复记录. 下面总结一下几种查找和删除重复记录的方法(以表CZ为例): 表CZ的结 ...

  2. oracle中查找执行效率低下的SQL

    v$sqltext:存储的是完整的SQL,SQL被分割 v$sqlarea:存储的SQL 和一些相关的信息,比如累计的执行次数,逻辑读,物理读等统计信息(统计) v$sql:内存共享SQL区域中已经解 ...

  3. oracle中查找某用户执行某张表的操作操作记录

    转载:http://www.cnblogs.com/nizuimeiabc1/p/9441937.html 1,首先查找表的操作记录 select * from v$sqlarea a where a ...

  4. oracle中查找与已知表的数据库对象

    在此次情况中,业务顾问就给我提供了一张客户公司客户化的Form,然后让找出界面上的数据是怎样生成的. 首先我们从EBS form 界面上找到了界面的数据来源于一张表ks_so_line_margin_ ...

  5. oracle中查找锁定状态的用户

    SQL> desc dba_users;desc dba_users; 名前 NULL? 型 ----------------------------------------- -------- ...

  6. java 11-8 在大串中查找小串的案例

    1.统计大串中小串出现的次数 举例: 在字符串"woaijavawozhenaijavawozhendeaijavawozhendehenaijavaxinbuxinwoaijavagun& ...

  7. Oracle中REGEXP_SUBSTR及其它支持正则表达式的内置函数小结

    Oracle中REGEXP_SUBSTR函数的使用说明: 题目如下:在oracle中,使用一条语句实现将'17,20,23'拆分成'17','20','23'的集合. REGEXP_SUBSTR函数格 ...

  8. Oracle中的内置函数在sql中的转换整理

    程序里面经常会即支持Oracle数据库,又支持sql数据库.而有些Oracle内置函数用的比较多,但在sql中语法有些不同,我做了些整理,希望可以帮助大家.... 1.oracle中的内置函数:ora ...

  9. oracle中的数据读取与查找

    数据读取 首先数据块读入到Buffer Cache中,并将其放在LRU(Last Recently Used)链表的MRU(Most Recently Used)端,当需要再次访问该块时可以直接从bu ...

随机推荐

  1. String、StringBuiler、StringBuffer的区别

    一.三者的区别概述 1.可变与不可变:String底层使用final修饰的字符数组来存储字符串,它属于不可变类,对String对象的任何改变操作都不会改变原对象,而是生成一个新对象.StringBui ...

  2. java中的函数式接口

    是什么?? 有且只有一个抽象方法的接口 场景: 适用于函数式编程场景(使用lambda表达式编程)的接口,函数式接口可以适用于lambda使用的接口. 只有确保接口中有且只有一个抽象方法,java中的 ...

  3. Memcache 与 Redis 的区别都有哪些?

    1.存储方式 Memecache 把数据全部存在内存之中,断电后会挂掉,数据不能 超过内存大小. Redis 有部份存在硬盘上,这样能保证数据的持久性. 2.数据支持类型 Memcache 对数据类型 ...

  4. Java 中,Comparator 与 Comparable 有什么不同?

    Comparable 接口用于定义对象的自然顺序,而 comparator 通常用于定义用户 定制的顺序.Comparable 总是只有一个,但是可以有多个 comparator 来定义 对象的顺序.

  5. Spring的@Enable*注解的工作原理

    转自:https://blog.csdn.net/chengqiuming/article/details/81586948 一 列举几个@Enable*注解的功能 @EnableAspectJAut ...

  6. 学习Kvm(五)

    KVM(一)搭建部署与概述 一,KVM概述 1.1 虚拟化概述 在计算机技术中,虚拟化意味着创建设备或资源的虚拟版本,如服务器,存储设备,网络或者操作系统等等 [x] 虚拟化技术分类: 系统虚拟化(我 ...

  7. 9_根轨迹_Part3_分离点/汇合点和根的性质

  8. 阿里云场景化阿里云企业数字化转型售前方法PSA

    阿里云场景化阿里云企业数字化转型售前方法PSA 目录 01 课程收获 理解企业数字化转型的概念.内涵.本质 了解企业数字化转型的要点.目标和切入点 掌握数字化转型项目售前阶段实践方法 场景化方案 阿里 ...

  9. 【Android开发】【布局】 仿QQ的UI

    Demo地址

  10. SQList基础+ListView基本使用

    今日所学: SQList基础语法 SDList下载地址 SQLite Download Page SQList安装教程SQLite的安装与基本操作 - 极客开发者-博客 ListView用法 没遇到什 ...