2011-07-29 3 views
1

私たちは大きなロケーションDBを持っています。 DBはMySQLでホストされています。の数と(カテゴリが列である)カテゴリー別 ロケーションデータベースを持つ大規模なMySQL DB(21MMレコード) - 各ロケーションに緯度経度があります。 '近くのクエリ'を実行する必要があります

  • 場所近く(距離によって並べ替え)
  • 近く

    • 場所:

      は、我々は、クエリの2種類を実行する必要がありますレコードが増加すると、このクエリは大幅に減速するようです。

      SELECT *, (3959 * acos(cos(radians(40.759105)) * cos(radians(Latitude)) * cos(radians(longitude) - radians(-73.984654)) + sin(radians(40.759105)) * sin(radians(Latitude)))) as distance FROM mcw_in WHERE Latitude <> '' ORDER BY distance LIMIT 0,20 
      

      遅さに対処するためにMySQLでインデックスを作成するにはどうすればよいですか?地理空間データ型のような他のソリューションはありますか?

    答えて

    0

    しかし、彼らは本当に機能を実装していないので、本当にこれは、MySQLで動作しません。

    オープンしていれば、私はPostGISまたはSpatialiate(それぞれPostgreSQLとSQLLite上で動作しています)またはmongodbまたはgeocouchを使用してください。これらは実装された空間関数のより大きなスイートを持っています。 MySQLのドキュメントを見ると、ほとんどの場合、空間関数には「実装されていません」と書かれています。

    0

    範囲照会は、中心を囲むバウンディングボックスを定義して使用する方がよいです。次のクエリは、距離($ lat0、$ lng0)から距離$ dist内の最も近い20の場所を検索し、その結果を距離でソートします。 'lat'と 'lng'の2つのインデックスが必要です。いくつかの説明はhereです。

    SELECT *, 
        (6371 * acos(
        cos(radians($lat0)) * cos(radians(lat)) * cos(radians(lng) - radians($lng0)) + 
        sin(radians($lat0)) * sin(radians(lat)) 
        )) AS distance 
    FROM `locations` 
    WHERE lat < degrees(asin(sin(radians($lat0)) * cos($dist/6371) + 
            cos(radians($lat0)) * sin($dist/6371) * cos(radians(0)))) 
      AND lat > degrees(asin(sin(radians($lat0)) * cos($dist/6371) + 
            cos(radians($lat0)) * sin($dist/6371) * cos(radians(180)))) 
      AND lng < $lng0 - degrees(atan2(sin(radians(90)) * sin(radians($dist/6371)) * cos(radians($lat0)), 
            cos(radians($dist/6371)) - sin(radians($lat0)) * sin(radians($lat0)))) 
      AND lng > $lng0 + degrees(atan2(sin(radians(90)) * sin(radians($dist/6371)) * cos(radians($lat0)), 
            cos(radians($dist/6371)) - sin(radians($lat0)) * sin(radians($lat0)))) 
    ORDER BY distance LIMIT 20; 
    
    関連する問題