sql語句查詢經緯度範圍

2021-10-04 04:45:28 字數 3209 閱讀 2787

指定乙個經緯度,給定乙個範圍值(單位:千公尺),查出在經緯度周圍這個範圍內的資料。

經度:113.914619

緯度:22.50128

範圍:2km

longitude為資料表經度字段

latitude為資料表緯度字段

sql在mysql下測試通過,其他資料庫可能需要修改

sql語句如下:

select * from location where sqrt( ( ((113.914619-longitude)*pi()12656cos(((22.50128+latitude)/2)*pi()/180)/180) * ((113.914619-longitude)*pi()12656cos (((22.50128+latitude)/2)*pi()/180)/180) ) + ( ((22.50128-latitude)*pi()*12656/180) * ((22.50128-latitude)*pi()*12656/180) ) )<2

mysql效能調優 – 使用更為快速的演算法進行距離

最近遇到了乙個問題,通過不斷的嘗試最終將某句原本佔據近1秒的查詢優化到了0.01秒,效率提高了100倍.

問題是這樣的,有一張存放使用者居住地點經緯度資訊的mysql資料表,表結構可以簡化 為:id(int),longitude(long),latitude()long. 而業務系統中有乙個功能是查詢離某個使用者最近的其餘數個使用者,通過**分析,可以確定原先的做法基本是這樣的:

//需要查詢的使用者的座標

$lat=20; $lon=20;//執行查詢,算出該使用者與所有其他使用者的距離,取出最近的10個 sql

=′se

lect

∗fro

muse

rslo

cati

onor

derb

yaco

s(si

n((′

.sql='select * from users_location order by acos(sin(('.

sql=′s

elec

t∗fr

omus

ersl

​oca

tion

orde

rbya

cos(

sin(

(′.lat.』 * 3.1415) / 180 ) *sin((latitude * 3.1415) / 180 ) +cos((』.lat

.′

∗3.1415)/

180)∗c

os((

lati

tude

∗3.1415)/

180)∗c

os((

′.

lat.' * 3.1415) / 180 ) * cos((latitude * 3.1415) / 180 ) *cos(('.

lat.′∗

3.14

15)/

180)

∗cos

((la

titu

de∗3

.141

5)/1

80)∗

cos(

(′.lon.』 * 3.1415) / 180 - (longitude * 3.1415) / 180 ) ) * 6380 asc limit 10』;

而這條sql執行的速度卻非常緩慢,用了近1秒的時間才返回結果,應該是因為order裡的子語句用了太多的數學計算公式,導致整體的運算速度下降.

而在實際的使用中,不太可能會發生需要計算該使用者與所有其他使用者的距離,然後再排序的情況,當使用者數量達到乙個級別時,就可以在乙個較小的範圍裡進行搜尋,而非在所有使用者中進行搜尋.

所以對於這個例子,我增加了4個where條件,只對於經度和緯度大於或小於該使用者1度(111公里)範圍內的使用者進行距離計算,同時對資料表中的經度和緯度兩個列增加了索引來優化where語句執行時的速度.

最終的sql語句如下

s ql

=′se

lect

∗fro

muse

rslo

cati

onwh

erel

atit

ud

e>′.

sql='select * from users_location where latitude > '.

sql=′s

elec

t∗fr

omus

ersl

​oca

tion

wher

elat

itud

e>′.

lat.』-1 and latitude < 『.lat

.′+1

andl

ongi

tude

>′.

lat.'+1 and longitude > '.

lat.′+

1and

long

itud

e>′.

lon.』-1 and longitude < 『.lon

.′+1

orde

rbya

cos(

sin(

(′

.lon.'+1 order by acos(sin(('.

lon.′+

1ord

erby

acos

(sin

((′.

lat.』 * 3.1415) / 180 ) sin((latitude * 3.1415) / 180 ) +cos((』.lat

.′

∗3.1415)/

180)∗c

os((

lati

tude

∗3.1415)/

180)∗c

os((

′.

lat.' * 3.1415) / 180 ) * cos((latitude * 3.1415) / 180 ) *cos(('.

lat.′∗

3.14

15)/

180)

∗cos

((la

titu

de∗3

.141

5)/1

80)∗

cos(

(′.lon.』 3.1415) / 180 - (longitude * 3.1415) / 180 ) ) * 6380 asc limit 10』;

sql語句查詢經緯度範圍

指定乙個經緯度,給定乙個範圍值 單位 千公尺 查出在經緯度周圍這個範圍內的資料。經度 113.914619 緯度 22.50128 範圍 2km longitude為資料表經度字段 latitude為資料表緯度字段 sql在mysql下測試通過,其他資料庫可能需要修改 sql語句如下 select ...

sql語句查詢經緯度範圍

指定乙個經緯度,給定乙個範圍值 單位 千公尺 查出在經緯度周圍這個範圍內的資料。經度 113.914619 緯度 22.50128 範圍 2km longitude為資料表經度字段 latitude為資料表緯度字段 sql在mysql下測試通過,其他資料庫可能需要修改 sql語句如下 select ...

sql語句查詢經緯度範圍

指定乙個經緯度,給定乙個範圍值 單位 千公尺 查出在經緯度周圍這個範圍內的資料。經度 113.914619 緯度 22.50128 範圍 2km longitude為資料表經度字段 latitude為資料表緯度字段 sql在mysql下測試通過,其他資料庫可能需要修改 sql語句如下 select ...