mysql geo 函数_【后端开发】地理位置geo处理之mysql函数的详细介绍(附代码)
本篇文章给大家带来的内容是关于地理位置geo处理之mysql函数的详细介绍(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
目前越来越多的业务都会基于LBS,附近的人,外卖位置,附近商家等等,现就讨论离我最近这一业务场景的解决方案。
目前已知解决方案有:mysql 自定义函数计算mysql geo索引mongodb geo索引postgresql PostGis索引redis geoElasticSearch
本文测试下mysql 函数运算的性能
准备工作
创建数据表
CREATE TABLE `driver` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`lng` float DEFAULT NULL,
`lat` float DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
创建测试数据
在创建数据之前先了解下基本的地理知识:
全球经纬度的取值范围为: 纬度-90~90,经度-180~180
中国的经纬度范围大约为: 纬度3.86~53.55,经度73.66~135.05
北京行政中心的纬度为39.92,经度为116.46
越北面的地方纬度数值越大,越东面的地方经度数值越大
度分转换: 将度分单位数据转换为度单位数据,公式:度=度+分/60
分秒转换: 将度分秒单位数据转换为度单位数据,公式:度 = 度 + 分 / 60 + 秒 / 60 / 60
在纬度相等的情况下:
经度每隔0.00001度,距离相差约1米
在经度相等的情况下:
纬度每隔0.00001度,距离相差约1.1米
mysql函数计算
DELIMITER //
CREATE DEFINER=`root`@`localhost` FUNCTION `getDistance`(
`lng1` float(10,7)
,
`lat1` float(10,7)
,
`lng2` float(10,7)
,
`lat2` float(10,7)
) RETURNS double
COMMENT '计算2坐标点距离'
BEGIN
declare d double;
declare radius int;
set radius = 6371000; #假设地球为正球形,直径为6371000米
set d = (2*ATAN2(SQRT(SIN((lat1-lat2)*PI()/180/2)
*SIN((lat1-lat2)*PI()/180/2)+
COS(lat2*PI()/180)*COS(lat1*PI()/180)
*SIN((lng1-lng2)*PI()/180/2)
*SIN((lng1-lng2)*PI()/180/2)),
SQRT(1-SIN((lat1-lat2)*PI()/180/2)
*SIN((lat1-lat2)*PI()/180/2)
+COS(lat2*PI()/180)*COS(lat1*PI()/180)
*SIN((lng1-lng2)*PI()/180/2)
*SIN((lng1-lng2)*PI()/180/2))))*radius;
return d;
END//
DELIMITER ;
创建数据python脚本
# coding=utf-8
from orator import DatabaseManager, Model
import logging
import random
import threading
""" 中国的经纬度范围 纬度3.86~53.55,经度73.66~135.05。大概0.00001度差距1米 """
# 创建 日志 对象
logger = logging.getLogger()
handler = logging.StreamHandler()
formatter = logging.Formatter(
'%(asctime)s %(name)-12s %(levelname)-8s %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)
# Connect to the database
config = {
'mysql': {
'driver': 'mysql',
'host': 'localhost',
'database': 'dbtest',
'user': 'root',
'password': '',
'prefix': ''
}
}
db = DatabaseManager(config)
Model.set_connection_resolver(db)
class Driver(Model):
__table__ = 'driver'
__timestamps__ = False
pass
def ins_driver(thread_name,nums):
logger.info('开启线程%s' % thread_name)
for _ in range(nums):
lng = '%.5f' % random.uniform(73.66, 135.05)
lat = '%.5f' % random.uniform(3.86, 53.55)
driver = Driver()
driver.lng = lng
driver.lat = lat
driver.save()
thread_nums = 10
for i in range(thread_nums):
t = threading.Thread(target=ins_driver, args=(i, 400000))
t.start()
以上脚本创建10个线程,10个线程插入4万条数据。耗费150.18s执行完,总共插入40万条数据
测试
测试环境
系统:mac os
内存:16G
cpu: intel core i5
硬盘: 500g 固态硬盘
测试下查找距离(134.38753,18.56734)这个坐标点最近的10个司机
select *,`getDistance`(134.38753,18.56734,`lng`,`lat`) as dis from driver ORDER BY dis limit 10
耗时:18.0s
explain:全表扫描
我测试了从1万到10万间隔1万和从10万到90万每间隔10万测试的结果变化
结论
此方案在数据量达到3万条查询耗时就会超过1秒
大约每增加1万条就会增加0.4秒的耗时
mysql geo 函数_【后端开发】地理位置geo处理之mysql函数的详细介绍(附代码)相关推荐
- python如何自定义函数_python如何自定义函数_后端开发
c语言特点是什么_后端开发 c语言特点是:1.语言简洁.紧凑,使用方便.灵活:2.运算符丰富:3.数据结构丰富,具有现代化语言的各种数据结构:4.具有结构化的控制语句:5.语法限制不太严度格,程序设计 ...
- 一个c语言源程序至少包括哪些内容,一个c源程序中至少应包括一个什么函数_后端开发...
PHP如何将PNG转换成JPG?_后端开发 PHP将PNG转换成JPG的方法:首先获取要转为JPG的PNG图片路径:然后通过"imagecreatefrompng()"函数,并根据 ...
- sprongboot mysql登录注册_后端开发:SpringBoot实现注册与登录功能
这次实现的注册与登录功能需要进行数据库的基本操作,而且是前后端分离式开发.总的来说就是首先进行数据库的设计,然后根据数据库进行编写服务端API接口,接着来到客户端或移动端,进行登录与注册的界面设计,接 ...
- python count函数代码_python count函数用法详解_后端开发
fgetc函数的作用详解_后端开发 fgetc函数的作用是从指定文件读入一个字符,要求文件的打开方式必须是以读或读写的方式或者追加的方 式,只写方式是不能读的. 在python中可以使用"c ...
- c语言中 n的意义,\n\n在c语言中是什么意思?_后端开发
PHP如何结合MySQL进行千万级数据处理_后端开发 一张一亿的订单表,可以分成五张表,这样每张表就只有两千万数据,分担了原来一张表的压力,分表需要根据某个条件进行分,这里可以根据地区来分表,需要一个 ...
- python中文意思k-python中“//”表示什么意思_后端开发
php如何去掉中文_后端开发 php去掉中文的方法:首先创建一个PHP示例文件:然后设置好"utf-8"编码:接着使用正则方法替换中文字符为空字符:最后保存并执行该文件即可.pyt ...
- python技术是什么意思_python中“//”表示什么意思_后端开发
php如何去掉中文_后端开发 php去掉中文的方法:首先创建一个PHP示例文件:然后设置好"utf-8"编码:接着使用正则方法替换中文字符为空字符:最后保存并执行该文件即可. py ...
- php无限评论回复_php实现无限级评论功能_后端开发
php去除数组的键名的方法_后端开发 在php中可以使用"array_values()"函数去除数组的键名,该函数返回包含数组中所有的值的数组,其语法是"array_va ...
- 加密php代码一担粮,分享8个PHP开发常用代码片段_后端开发
php字符串转时间戳_后端开发 在php中可以使用"strtotime()"函数将字符串转为时间戳,该函数用于把字符串转换为时间戳,其语法是"strtotime(time ...
- python统计中文字符的个数_python统计不同字符的个数_后端开发
c++怎么将字符串转数字_后端开发 在"c++"中可以使用"atoi"库函数将字符串转成数字,其语法是"int atoi(const char *np ...
最新文章
- dhtmlxgrid表格笔记
- java web 教案_《Java web程序设计》教案.pdf
- python 基础之第四天
- 粒子群优化算法_每日论文19:粒子群优化算法综述
- 一篇文章带你详解 TCP/IP 协议(下)
- Flex 3 与 Flex 4 beta 之间的区别
- 54.get set
- linux c之memcpy拷贝结构体到结构体、拷贝字符数组到结构体
- Coursera课程 Programming Languages, Part C 总结
- 计算机图形学图形旋转_计算机图形学翻译
- MyBatis 的执行流程,学废了!
- 使用c++制作微服务计算服务
- 错误的日志可能会导致疯狂;好日志可能会成为魔杖
- 老外的一个用的SQLite的例子,看起来比较初级
- paip.解决 数据库mysql增加列 字段很慢添加字段很慢
- python选择时间窗口_对pandas中时间窗函数rolling的使用详解
- 苹果手机测距离_手机传感器怎样运作 手机传感器工作原理【介绍】
- 微信小程序登录后,用户名显示微信用户,头像显示灰色,用户自己的头像和名称无法正常显示的问题(附解决方案)
- 打开运行PS、AI等软件时卡在启动窗口的解决办法
- 第一周 Web开发入门(下)
热门文章
- 你知道在深圳一个月花多少钱吗?
- spring中的事务到底是什么
- 微信小程序(小游戏)后台开发
- Scrapy实现微博关键词爬虫(爬虫结果写入mongodb)
- 我一直认为生意人行走江湖
- Spark工作原理及基础概念
- 你想当程序员,升职CEO,迎娶白富美,走向人生巅峰?那这篇职业发展路线图你有必要看一遍!!(完整版+珍藏版)
- 正交标注有利于无监督医学图像分割
- Linux怎么接移动热点,Linux网络配置:手提在连接WIFI热点情况下,Ubuntu16.04中怎样配置网络?...
- svn 小乌龟没有详细日志