首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 經緯度距離排序查詢:Haversine 公式實戰與效能優化思路

     編輯:MySQL 資料庫相關知識

核心 SQL(Haversine 公式)

SELECT *,
  (2 * 6378.137 * ASIN(SQRT(
    POW(SIN(PI() * (111.86141967773438 - lat) / 360), 2) +
    COS(PI() * 33.07078170776367 / 180) *
    COS(lat * PI() / 180) *
    POW(SIN(PI() * (33.07078170776367 - lng) / 360), 2)
  ))) AS juli
FROM `area`
ORDER BY juli ASC
LIMIT 0, 20;
  • 6378.137:地球半徑(公里)。
  • lat、lng:資料表經緯度欄位。
  • 111.8614..., 33.0707...:目標座標(此處為範例值)。
  • 結果 juli 為公里數,按升序取最近 20 筆。

效能瓶頸與優化方向

全表掃描 + 三角函數運算極慢,尤其資料量大時。優化思路:

  1. 平面座標轉換:若範圍較小(如同城),可將經緯度投影為平面座標(如 UTM、高斯-克吕格),改用歐幾里得距離,並建立空間索引。
  2. 經度範圍預過濾:先用經度差估算粗略距離,過濾掉明顯過遠的行,再精確計算。
  3. MySQL 5.7+ 空間擴展:使用 ST_Distance_Sphere、ST_Distance 及空間索引(SPATIAL INDEX)。
  4. Redis Geo / PostgreSQL PostGIS:大規模 LBS 業務建議外掛專用空間引擎。

MySQL 8.0 範例

SELECT *, ST_Distance_Sphere(POINT(lng, lat), POINT(116.39, 39.90)) AS dist
FROM `area`
ORDER BY dist ASC
LIMIT 20;
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved