[英]Improving performance of spatial MySQL query
我有一個查詢,該查詢返回所有記錄,這些記錄按距固定點的距離進行排序,與MySQL 5.7數據庫中的POINT
字段相比。
對於一個簡單的例子,可以說它看起來像這樣:
SELECT shops.*, st_distance(location, POINT(:lat, :lng)) as distanceRaw
FROM shops
ORDER BY distanceRaw
LIMIT 50
我的實際查詢還必須進行一些連接才能獲取結果的其他數據。
問題是,為了按距離對數據進行排序,它需要計算數據庫中每條記錄(當前大約100,000條記錄)的距離。
我無法緩存查詢,因為它僅特定於那些原始坐標。
無論如何,有沒有限制必須計算的數據? 例如,對附近商店進行可靠的粗略計算,例如lat
+ lng
+/- 3度? 這樣它只需要處理一部分數據?
如果有人對這種優化有任何經驗,我很樂意提供一些建議,謝謝。
是的,您可以使用一些簡單的近似值,根據其中的條件來過濾掉半徑之外的那些位置。 這篇很棒的博客文章標題為“針對SQL(MySQL,PostgreSQL,SQL Server)的快速最近位置查找器”描述了這樣的優化:
請記住,根據本文前面的背景信息,緯度為111.045公里。 因此,如果我們在緯度列上有索引,則可以使用像這樣的SQL子句來消除太北或太南以至於50公里之內的點。
latitude BETWEEN latpoint - (50.0 / 111.045) AND latpoint + (50.0 / 111.045)
這個WHERE子句允許MySQL在計算hasrsine距離公式之前使用索引來省略很多緯度點。 它允許MySQL對緯度索引執行范圍掃描。
最后,我們可以使用類似但更復雜的SQL子句來消除太遠或太遠的點。 該子句更加復雜,因為經度越遠離我們移動的赤道,距離就越小。 這是公式。
longitude BETWEEN longpoint - (50.0 / (111.045 * COS(RADIANS(latpoint)))) AND longpoint + (50.0 / (111.045 * COS(RADIANS(latpoint))))
因此,將所有內容放在一起,此查詢將找到(緯度,經度)50公里邊界框內的近15個點。
上面描述了邊界矩形的理論背景。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.