lbs中從庫中查詢某經緯度2KM範圍內的資料

2021-09-01 13:35:28 字數 2052 閱讀 1096

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

經度:113.914619 

緯度:22.50128 

範圍:2km 

longitude為資料表經度字段 

latitude為資料表緯度字段 

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

sql語句如下: 

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

最近遇到了乙個問題,通過不斷的嘗試最終將某句原本佔據近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.'

+1order 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查詢範圍的方法也可以適用在其他地方.

Android中如何獲取經緯度

前提是 在這之前jingwd 方法被呼叫過了,比如放在oncreate 裡,因為這裡面 是具體的實現,下面是 private locationmanager locationmanager private string locationprovider 經緯度獲取 private void jing...

Cesium中實時顯示經緯度及視角高

如何在cesium中實時根據滑鼠的位置顯示經緯度以及視角高 具體效果如下 具體 如下 html 經度 緯度 視角高 km 相應的js var longitude show document.getelementbyid longitude show var latitude show documen...

在 Oracle 中根據經緯度計算兩地之間的距離

在 oracle 中根據經緯度計算兩地之間的距離 獲得弧度的函式 create or replace function radian d number return number ispi number 3.141592625 begin return d pi 180.0 end 測試一下這個函式...