1

MYSQL の POINT データ型を使用して格納されている緯度と経度の座標を使用してテーブルをクエリする必要があるアプリケーションがあります。

特定の GPS 位置の特定の半径内で近くの緯度と経度を検索するストアド関数があります。ただし、私のテーブルには数十万のエントリが含まれるため、パフォーマンスを最適化する必要があります。

次のストアド関数を作成しましたが、800,000 行以上の可能性がある中、約 9,000 行を返すのに約 4.01 秒かかります。近くの GPS 座標を見つけるより良い方法はありますか?

これが私の保存された関数です:

    CREATE PROCEDURE `FindNearbyPoints`(
    IN RADIUS FLOAT,
    IN LAT FLOAT,
    IN LON FLOAT
)
BEGIN

    DECLARE EARTH_RADIUS FLOAT DEFAULT 3959;
    DECLARE maxLat FLOAT DEFAULT (LAT + DEGREES(RADIUS/EARTH_RADIUS));
    DECLARE minLat FLOAT DEFAULT (LAT - DEGREES(RADIUS/EARTH_RADIUS));

    /* compensate for degrees longitude getting smaller with increasing latitude*/
    DECLARE maxLon FLOAT DEFAULT (LON + DEGREES(RADIUS/EARTH_RADIUS/COS(RADIANS(LAT))));
    DECLARE minLon FLOAT DEFAULT (LON - DEGREES(RADIUS/EARTH_RADIUS/COS(RADIANS(LAT))));

    SELECT *, acos(sin(LAT)*sin(radians(X(Location))) + cos(LAT)*cos(radians(X(Location)))*cos(radians(Y(Location))-LON))*EARTH_RADIUS As D
    FROM (
        Select *
        From my_table
        Where X(Location)>minLat And X(Location)<maxLat
        And Y(Location)>minLon And Y(Location)<maxLon
    ) AS FIRST_CUT
    WHERE acos(sin(LAT)*sin(X(Location)) + cos(LAT)*cos(X(Location))*cos(Y(Location)-LON))*EARTH_RADIUS < RADIUS
    ORDER BY D;

END

関数に対する私のインスピレーションの多くは、http ://www.movable-type.co.uk/scripts/latlong-db.html から得ました。

4

1 に答える 1

0

データベースがどのように設定されているかはわかりませんが、SPATIAL インデックスを使用してから、最小限の境界四角形を構築してクエリを実行することを検討してください。境界ボックスを介してレコードを返すと、それらを距離ですばやく並べ替えて、半径の外側にあるレコードを除外できます。私たちはこの種の索引付けをゲノミクスで使用し、日常的に 10 億行のデータセットを非常に効果的にクエリしています。

mysql docs に空間インデックス作成の詳細があります。

于 2010-10-19T18:49:39.090 に答える