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

使用されていない空間インデックス

    残念ながら、 ST_Distance() < threshold sargable ではありません 検索基準。このクエリを満たすには、MySQLはテーブル内のすべての行の関数の値を計算し、それをしきい値と比較する必要があります。したがって、全表スキャン(または全表スキャン)を実行する必要があります。

    インデックスを利用してこのクエリを高速化するには、バウンディングボックス基準が必要になります。クエリははるかに複雑ですが、はるかに高速です。ジオメトリのx/yポイントが緯度/経度を度で表すとすると、そのクエリは次のようになります。

       set @latpoint = 38.0234332;
       set @lngpoint = -94.0724223;
       set @r = 10.0;    /* ten mile radius */
       set @units=69.0;    /* 69 statute miles per degree */
       SELECT AsText(geo) 
         FROM markers
          WHERE MbrContains(GeomFromText( 
           CONCAT('LINESTRING(', @latpoint-(@r/@units),' ',
                                 @lngpoint-(@r /(@units* COS(RADIANS(@latpoint)))), 
                              ',', 
                                 @latpoint+(@r/@units) ,' ', 
                                 @lngpoint+(@r /(@units * COS(RADIANS(@latpoint)))),
                               ')')),
                        geo) 
    

    これはどのように作動しますか?一つには、 MbrContains(バウンド、アイテム) 関数です sargable 。別のこととして、大きな醜いコンキャットアイテムは、境界長方形の南西から北東の角に対角線を生成します。データポイントと半径10マイルを使用すると、次のようになります。

    LINESTRING(37.8785 -94.2564,38.1684 -93.8884)
    

    GeomFromText()を使用する場合 MbrContains()の最初の引数でのその対角線のレンダリング 境界矩形として機能します。 MbrContains() その後、気の利いた四分木ジオメトリインデックスを活用できます。

    第三に、ST_Distance() 、MySQLでは、大円の緯度と経度の計算を処理しません。 ( PostgreSQL より包括的なGIS拡張機能 があります 。)MySQLは、平地のフラップジャックと同じくらい馬鹿げています。ジオメトリックオブジェクト内のポイントが平面ジオメトリで表されていることを前提としています。したがって、ST_Distance() < 10.0 lng/latポイントで何か奇妙なことをします。

    このクエリが生成する結果には1つの欠陥があります。指定された半径内だけでなく、バ​​ウンディングボックス内のすべてのポイントを返します。これは、別の距離計算で解決できます。私はこれをすべてここに詳細に記述しました 。

    :GPS解像度の緯度と経度の場合、32ビットのFLOAT データには十分な精度があります。 DOUBLE MySQLのgeo拡張機能が使用するものです。度で作業している場合、小数点以下5桁以上はGPSの精度を超えています。 DECIMAL() 緯度/経度座標の理想的なデータ型ではありません。




    1. SQL Server アリサボート

    2. 簡単な全文検索をお探しですか? MySQL InnoDB+CakePHPとWordStemmingをお試しください

    3. phpを使用してhtmlテーブルにmysql行のコンテンツを表示する

    4. SQLServerストアドプロシージャで動的where句を作成する