sql >> データベース >  >> RDS >> Mysql

距離パフォーマンスを備えたMYSQLGeoSearch

    これを行う最も速い方法は、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の作成に使用する関数を個人的に定義しました 。



    1. インラインvarchar(max)列を使用する必要がありますか、それとも別のテーブルに保存する必要がありますか?

    2. SQLAlchemyORMを使用した一括挿入

    3. 文字列リテラルが長すぎます-Oracle11gr2で長いxmlデータをclobデータ型に割り当てる方法

    4. パフォーマンスの問題を回避するための代替によるSQLカーソルの置き換え