sql語句查詢經緯度範圍

2022-03-20 05:54:16 字數 3863 閱讀 7123

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

經度: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()/180)/180)

* ((113.914619-longitude)*pi()*12656*cos (((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='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查詢範圍的方法也可以適用在其他地方.

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

經度: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()/180)/180)

* ((113.914619-longitude)*pi()*12656*cos (((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='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語句查詢經緯度範圍

指定乙個經緯度,給定乙個範圍值 單位 千公尺 查出在經緯度周圍這個範圍內的資料。經度 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 ...