5

squares次のテーブル構造を持つ約 2,250,000 行を持つInnoDB エンジンで実行されている MySQL テーブルがあります。

`squares` (
   `square_id` int(7) unsigned NOT NULL,
   `ref_coord_lat` double(8,6) NOT NULL,
   `ref_coord_long` double(9,6) NOT NULL,
   PRIMARY KEY (`square_id`),
   KEY `ref_coord_lat` (`ref_coord_lat`),
   KEY `ref_coord_long` (`ref_coord_long`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

最初の列square_idは 0 から 2.25M までの単純な増分値を保持し、 ref_coord_lat&ref_coord_longはポイントの緯度と経度の座標のセットをそれぞれ 10 進数で保持します。

これは読み取り専用のテーブルです。追加の行は追加されず、それに対して実行する必要がある唯一のクエリは次のとおりです。

SELECT * FROM `squares` WHERE 
  `ref_coord_lat` BETWEEN :southLat AND :northLat AND 
  `ref_coord_long` BETWEEN :westLong AND :eastLong

...ここで、コロンに続く値は PHP PDO プレースホルダーです。基本的に、このクエリの目的は、現在 Google マップ ウィンドウのビューポートにあるテーブル内のすべての座標点を取得することです。この座標点は、クエリ内の 4 つの座標で囲まれています。

このクエリが Google Maps API で実行されるズーム レベルを制限したため、フェッチできる最大行数は~5600です。ズーム レベルが上がると、結果として得られるフェッチの合計は大幅に減少します。

このようなサンプル クエリを PHPMyAdmin で直接実行すると、1.40 ~ 1.45 秒かかります。これは長すぎます。私はすでに標準インデックスを実行してref_coord_latおり、ref_coord_longこれによりクエリ時間が約 5 秒から短縮されましたが、これはエンド ユーザーがタイムリーな応答を期待するマップにはまだ大きすぎます。

私の質問は単純です:このテーブル/クエリをさらに最適化して、結果がフェッチされる速度を上げるにはどうすればよいですか?

4

4 に答える 4

3

あなたの構造はかなり問題ないようです。2,25M 行はそれほど多くありません。行が小さく、行う比較は double 値のみです。それはより速いはずです。

、、、コマンドをテーブルで実行ANALYZEして、インデックスが正しく構築されていることを確認してください。OPTIMIZECHECKREPAIR

これが完了したら、システムをより深く調査してみてください。何がクエリを遅くしていますか? かもね :

  • ディスク I/O
  • メモリ制限 (my.cnf を調整してみてください。優れたhttp://www.mysqlperformanceblog.com/を参照してください)
  • CPU(ありそうにない)
  • ネットワークの問題

監視を使用して、SQL キャッシュ、メモリ使用量などに関するデータを取得します。問題の診断に役立ちます。

あなたのプロジェクトで頑張ってください。

于 2013-08-13T07:18:08.443 に答える
3

複合インデックスを作成(lat, long)すると、大いに役立つはずです。

ただし、正しい解決策は、MySQL 空間拡張機能を確認することです。空間サポートは、2 次元データとそのようなデータに対するクエリを処理するために特別に作成されました。適切な空間インデックスを作成すると、通常のクエリ パフォーマンスは、上の複合インデックスのパフォーマンスを簡単に超えるはず(lat, long)です。

于 2013-08-13T08:56:12.693 に答える