sql语句查询经纬度范围(转载,源链接失效)

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

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

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

//需要查询的用户的坐标

$lat=20; $lon=20;//执行查询,算出该用户与所有其他用户的距离,取出最近的10个
 $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语句如下

$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查询范围的方法也可以适用在其他地方.

时间: 2024-10-05 05:05:03

sql语句查询经纬度范围(转载,源链接失效)的相关文章

sql语句查询经纬度范围

指定一个经纬度,给定一个范围值(单位:千米),查出在经纬度周围这个范围内的数据. 经度:113.914619 纬度:22.50128 范围:2km longitude为数据表经度字段 latitude为数据表纬度字段 SQL在mysql下测试通过,其他数据库可能需要修改 SQL语句如下: select * from location where sqrt( ( ((113.914619-longitude)*PI()*12656*cos(((22.50128+latitude)/2)*PI()/

sql语句查询同一表内多字段同时重复的记录 sql数据库重复记录删除

分享下用sql语句删除数据库中重复记录的方法.比如现在有一人员表 (表名:peosons) 若想将姓名.身份证号.住址这三个字段完全相同的记录查询出来select p1.* from persons p1,persons p2 where p1.id<>p2.id and p1.cardid = p2.cardid and p1.pname = p2.pname and p1.address = p2.address可以实现上述效果.几个删除重复记录的SQL语句 1.用rowid方法2.用gr

如何用SQL语句查询Excel数据?

如何用SQL语句查询Excel数据?Q:如何用SQL语句查询Excel数据? A:下列语句可在SQL SERVER中查询Excel工作表中的数据. 2007和2010版本: SELECT*FROMOpenDataSource( 'Microsoft.ACE.OLEDB.12.0', 'Data Source="c:\book1.xlsx";User ID=Admin;Password=;Extended properties=Excel 12.0')...[Sheet1$] 复制代码

SQL语句分类:幸运飞艇源码搭建

SQL语句分类:幸运飞艇源码搭建(企 娥:217 1793 408) DDL:数据定义(对数据库和表结构的,增.删.改) 创建表:create table 表名(字段名 类型 [其他],....); 删除表:drop table 表名 修改:alter table 表名 add/modify/change/drop/rename to XXXX ** DML:数据操作(对表记录的操作,增.删.改) 添加:insert into 表名(字段名...) values(值....); 删除:delet

利用SQL语句查询SCCM常用报表

2019年仅剩4天了,回头一看,今年都还没有写过博客.趁着2019的尾巴,分享一下今年做的SCCM项目经验.主要是关于如何通过SQL语句来查询SCCM相关报表信息.言归正传,默认安装报表服务后,可通过中心管理站点在sccm管理控制台查看报表数据,但是个人觉得自带的报表不好用,导出来的数据格式带各种链接,没有直接通过SQL查询报表来的方便.以下是通过SQL语句查询的常用10种SCCM统计报表: 1.系统发现数据System_Disc报表--查看SCCM系统发现的数据 2.计算机IP地址2.1 Sy

sql语句查询后几行数据并倒着排列

$conn = mysql_connect("数据库地址","用户名","密码"); if(!$conn) { die("mysql conn failed"); } else{ mysql_query("SET NAMES 'utf8'"); mysql_select_db("数据表",$conn); if(!$conn) { die("database selected f

提高SQL语句查询效率

1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: select id from t where num is null 可以在num上设置默认值0,确保表中num列没有null值,然后这样查询: select id from t where num=0 3.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放

sql语句查询重复的数据

查找所有重复标题的记录:SELECT *FROM t_info aWHERE ((SELECT COUNT(*)FROM t_infoWHERE Title = a.Title) > 1)ORDER BY Title DESC一.查找重复记录1.查找全部重复记录Select * From 表 Where 重复字段 In (Select 重复字段 From 表 Group By 重复字段 Having Count(*)>1)2.过滤重复记录(只显示一条)Select * From HZT Whe

sql语句查询条件的不同表达方式对查询性能的影响

今天操作数据库遇到一个问题 目标表RA_AD_DAILY_DATA的数据量大概有5千万左右,其中的BUSINESS_DATE字段为日期类型 我要查询8月20号导入的三条记录,刚开始用这种方式去查: SELECT * FROM RA_AD_DAILY_DATA WHERE  to_char(BUSINESS_DATE,'yyyy-MM-dd')= '2014-08-20' ; 速度非常慢,五分钟左右才能出来结果(在PL/SQL developer中) 同样都是查询2014年8月20日的数据,换一种