需求:

  已知一个点的经纬度,需要从表中找出以这个点为中心,半径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. Kafka 新旧消费者的区别?

    旧的 Kafka 消费者 API 主要包括:SimpleConsumer(简单消费者) 和 ZookeeperConsumerConnectir(高级消费者).SimpleConsumer 名字看起来 ...

  2. 用 Java 写一个折半查找?

    折半查找,也称二分查找.二分搜索,是一种在有序数组中查找某一特定元素的搜索算法. 搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束:如果某一特定元素大于或者小于中间元素,则 ...

  3. 学习MySql(一)

    一.安装部署mysql 1.安装mysql: # yum -y install autoconf libaio libaio-devel # groupadd mysql # useradd -r - ...

  4. 学习RabbitMQ(四)

      I. 消息中间件特点: 1,异步处理模式 消息发送者可以发送一个消息而无需等待响应,消息发送者将消息发送到一条虚拟的通道或队列上,消息接收者则订阅或监听该通道,一条消息可能最终转发给一个或多个消息 ...

  5. 学习saltstack (一)

    salt介绍 Salt是一个基础平台管理工具 Salt是一个配置管理系统,能够维护预定义状态的远程节点 Salt是一个分布式远程执行系统,用来在远程节点上执行命令和查询数据 salt的核心功能 是命令 ...

  6. npm run start 后台运行

    yum provides */nohup nohup npm start & 原程序的的标准输出被自动改向到当前目录下的nohup.out文件,起到了log的作用. 停止程序   ps -ef ...

  7. 攻防世界 Ditf misc

    Ditf 附件下载下来就是一张图片,我们拉到hxd中发现应该有隐藏的压缩包 我们拉入到kali里面分析 意外发现图片高度被修改过我们先用binwalk分析图片看看 我们先尝试分离一下分离出一个压缩包但 ...

  8. 制作html5微信页面的经验总结。

    先罗列一下我遇到的问题: 用户可选择图片上传,但是图片比较大(基本都是2M以上),而且还得异步上传. 由于操作上比较多的设计都是隐性的例如滑动之类,需要手势动画作提示. 块内元素滚动时不流畅,或不能滚 ...

  9. 实验 3 Spark 和 Hadoop 的安装

      1.           安装 Hadoop 和 Spark 进入 Linux 系统,参照本教程官网"实验指南"栏目的"Hadoop 的安装和使用",完成 ...

  10. PAT B1081 检查密码

    题目描述: 本题要求你帮助某网站的用户注册模块写一个密码合法性检查的小功能.该网站要求用户设置的密码必须由不少于6个字符组成,并且只能有英文字母.数字和小数点 .,还必须既有字母也有数字. 输入格式: ...