これを行う最も速い方法は、MySQLの地理空間拡張機能を使用することです。これは、すでにMyISAMテーブルを使用しているので十分簡単です。これらの拡張機能のドキュメントは、次の場所にあります: http:/ /dev.mysql.com/doc/refman/5.6/en/spatial-extensions.html
POINTデータ型の新しい列を追加します:
ALTER TABLE `adverts`
ADD COLUMN `geopoint` POINT NOT NULL AFTER `longitude`
ADD SPATIAL KEY `geopoint` (`geopoint`)
次に、既存の緯度と経度のフィールドからこの列にデータを入力できます。
UPDATE `adverts`
SET `geopoint` = GeomFromText(CONCAT('POINT(',`latitude`,' ',`longitude`,')'));
次のステップは、WHERE
で使用される入力緯度と経度に基づいて境界ボックスを作成することです。 CONTAINS
としての句 制約。 X、YのPOINT
のセットを決定する必要があります 目的の検索領域と指定された開始点に基づいて、要件に合わせて機能する座標。
最後のクエリでは、すべてのPOINT
が検索されます 検索内のデータPOLYGON
、そして距離計算を使用して、データをさらに絞り込み、並べ替えることができます。
SELECT a.*,
ROUND( SQRT( ( ( (adverts.latitude - '53.410778') * (adverts.latitude - '53.410778') ) * 69.1 * 69.1 ) + ( (adverts.longitude - '-2.97784') * (adverts.longitude - '-2.97784') * 53 * 53 ) ), 1 ) AS distance
FROM adverts a
WHERE a.type_id = 3
AND CONTAINS(a.geopoint, GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))'))
HAVING distance < 25
ORDER BY distance DESC
LIMIT 0, 30
GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))')
上記では機能しません 、検索開始の周囲の有効なポイントで座標を置き換える必要があります。緯度/経度が変化すると予想される場合は、トリガーを使用してPOINT
を維持することを検討する必要があります データと関連するSPATIAL KEY
最新の。大規模なデータセットでは、すべてのレコードの距離を計算し、HAVING
を使用してフィルタリングするよりもパフォーマンスが大幅に向上するはずです。 句。距離の決定と境界POLYGON
の作成に使用する関数を個人的に定義しました 。