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

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

  1. sql语句查询经纬度范围

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

  2. [转载]编写SQL语句查询出每个各科班分数最高的同学的名字,班级名称,课程名称,分数

    [转载]编写SQL语句查询出每个各科班分数最高的同学的名字,班级名称,课程名称,分数 转载自:https://blog.csdn.net/one_money/article/details/56921 ...

  3. 【转载】C#常用数据库Sqlserver通过SQL语句查询数据库以及表的大小

    在Sqlserver数据库中,一般我们查看数据库的大小可以通过查找到数据库文件来查看,但如果要查找数据表Table的大小的话,则不可通过此方法,在Sqlserver数据库中,提供了相应的SQL语句来查 ...

  4. 浅谈MySQL中优化sql语句查询常用的30种方法 - 转载

    浅谈MySQL中优化sql语句查询常用的30种方法 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中使 ...

  5. phpcmsv9自定义sql语句查询模型实现

    在phpcmsv9中,自定义sql语句查询可不太好实现,传入sql语句查询很容易被内部转入生成一系列莫名其妙的sql语句,比如最佳前缀等等,直接造成sql语句查询错误,在此也提供两种解决办法,1修改底 ...

  6. 怎样用SQL语句查询一个数据库中的所有表?

    怎样用SQL语句查询一个数据库中的所有表?  --读取库中的所有表名 select name from sysobjects where xtype='u'--读取指定表的所有列名select nam ...

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

    如何用SQL语句查询Excel数据?Q:如何用SQL语句查询Excel数据? A:下列语句可在SQL SERVER中查询Excel工作表中的数据. 2007和2010版本: SELECT*FROMOp ...

  8. [转]关于oracle sql语句查询时表名和字段名要加双引号的问题

    oracle初学者一般会遇到这个问题.   用navicat可视化创建了表,可是就是不能查到!   后来发现②语句可以查询到 ①select * from user; 但是,我们如果给user加上双引 ...

  9. mysql / pgsql 使用sql语句查询数据库所有表注释已经表字段注释

    mysql使用sql语句查询数据库所有表注释已经表字段注释(转载)   场景: 1. 要查询数据库 "mammothcode" 下所有表名以及表注释 /* 查询数据库 ‘mammo ...

随机推荐

  1. dhcp协议交互报文

    DHCP共有八种报文,分别为DHCP Discover.DHCP Offer.DHCP Request.DHCP ACK.DHCP NAK.DHCP Release.DHCP Decline.DHCP ...

  2. PHP安装mysql.so扩展

    在PHP中mysql_connect模块已经逐渐被弃用,我在搭建环境时也没有再安装mysql扩展,但是今天在维护一个老项目时,出现报错 Fatal error: Uncaught Error: Cal ...

  3. 原创:CSS3技术-雪碧图自适应缩放与精灵动画方案

    花了一个礼拜完成了慕课网定制的七夕主题效果,其中有一个没实现好的功能,就是雪碧图的自适应缩放 ps: 以下实现都是基于移动端的处理 原图如下: 人物是采用的是雪碧图,通过坐标绝对数据取值 问题很明显, ...

  4. 当master down掉后,pt-heartbeat不断重试会导致内存缓慢增长

    最近同事反映,在使用pt-heartbeat监控主从复制延迟的过程中,如果master down掉了,则pt-heartbeat则会连接失败,但会不断重试. 重试本无可厚非,毕竟从使用者的角度来说,希 ...

  5. 一个技术汪的开源梦 —— 基于 .Net Core 的组件 Nuget 包制作 & 发布

    一个技术汪的开源梦 —— 目录 微软的 ASP.Net Core 强化了 Nuget 的使用,所有的 .Net Core 组件均有 Nuget 管理,所以有必要探讨一下 .Net Core 组件制作 ...

  6. [摘录]第三部分 IBM文化(1)

    第二十章 论公司文化如果是在20世纪90年代初期,当一个人看见或者听到“IBM”时,他会联想到什么呢?或许是“大计算机”.“个人电脑”或者“ThinkPads”.但是,他们同时也必然会想到“大公司”. ...

  7. 【NLP】Python NLTK 走进大秦帝国

    Python NLTK 走进大秦帝国 作者:白宁超 2016年10月17日18:54:10 摘要:NLTK是由宾夕法尼亚大学计算机和信息科学使用python语言实现的一种自然语言工具包,其收集的大量公 ...

  8. jQuery对象和DOM对象的区别

    jQuery对象和DOM对象使用说明,需要的朋友可以参考下.1.jQuery对象和DOM对象第一次学习jQuery,经常分辨不清哪些是jQuery对象,哪些是 DOM对象,因此需要重点了解jQuery ...

  9. 『.NET Core CLI工具文档』(一).NET Core 命令行工具(CLI)

    说明:本文是个人翻译文章,由于个人水平有限,有不对的地方请大家帮忙更正. 原文:.NET Core Command Line Tools 翻译:.NET Core命令行工具 什么是 .NET Core ...

  10. 随机记录工作中常见的sql用法错误(一)

    没事开始写博客,留下以前工作中常用的笔记,内容不全或者需要补充的可以留言,我只写我常用的. 网上很多类似动软生成器的小工具,这类工具虽然在表关系复杂的时候没什么软用,但是在一些简单的表结构关系还是很方 ...