MySQLで空間インデックスを使用するとパフォーマンスが低下する


13

これがより良いフォーラムであると示唆されたとき、Stack Overflowで尋ねられた質問の再投稿。

私は、地理空間ではないが非常によく適合するデータセットをプッシュするために少し実験を試みていますが、結果はやや不安定です。データセットはゲノムデータです。たとえば、遺伝子などの要素が特定の開始座標と停止座標(X軸)を占めるDNA領域があるHuman Genomeです。Y軸を占めるDNAの複数の領域(染色体)があります。目標は、単一のY座標に沿って2つのX座標と交差するすべてのアイテム、たとえばLineString(START 1、END 2)を戻すことです。

理論は健全に思えたので、既存のMySQLベースのゲノムプロジェクトにそれをプッシュし、次のようなテーブル構造を思い付きました。

CREATE TABLE `spatial_feature` (
  `spatial_feature_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `external_id` int(10) unsigned NOT NULL,
  `external_type` int(3) unsigned NOT NULL,
  `location` geometry NOT NULL,
  PRIMARY KEY (`spatial_feature_id`),
  SPATIAL KEY `sf_location_idx` (`location`)
) ENGINE=MyISAM;

external_idこのテーブルにエンコードしたエンティティの識別子を表し、このexternal_typeソースをエンコードします。すべてが順調に見えたので、いくつかの予備データ(30,000行)を入力しましたが、これはうまくいくようです。これが300万行のマークを超えて増加すると、MySQLは空間インデックスの使用を拒否し、使用を強制されたときに遅くなりました(40秒対全テーブルスキャンを使用した5秒)。さらにデータが追加されると、インデックスの使用が開始されましたが、パフォーマンスの低下が続きました。インデックスを強制的にオフにすると、クエリは8秒になりました。私が使用しているクエリは次のようになります。

select count(*)
from spatial_feature
where MBRIntersects(GeomFromText('LineString(7420023 1, 7420023 1)'), location);

これに入力されるデータは、Y次元に沿って非常に密集しています(非常に長い道路上のすべての建物、電話ボックス、郵便ボックス、鳩の位置を記録したと考えてください)。Javaでこのデータを使用してR-Indexがどのように動作するかをテストし、フィールドの他のユーザーがそれらをフラットファイル形式に適用して成功しました。ただし、このテストの目標であるデータベースに誰もそれらを適用していません。

特定の軸に沿ってあまり分散していない空間モデルに大量のデータを追加すると、そこにいる誰かが同様の動作を見ましたか?座標の使用を逆にしても問題は解決しません。それが原因である場合、私は次のセットアップを実行しています

  • MacOS 10.6.6
  • MySQL 5.1.46

回答:


5

MySQLは、PostGISと同様に、空間インデックスデータをRツリー構造に格納するため、高速でデータを見つけることができます。Rツリーは、Bツリーと同様に、テーブル内の全データのごく一部のみを取得するために最適化されるように編成されます。実際には、テーブルの大きなセクションを読み取ってデータを返すか、巨大な結合を実行する必要があるクエリのインデックスを無視する方が高速です。これは、多くのデータベースフォーラム[投稿者]表「作成したばかりの新しいインデックスを使用していません。」

http://rickonrails.wordpress.com/2009/03/30/big-ole-mysql-spatial-table-optimization-tricks/から

すべてのテーブルデータをメモリに収めることができれば、パフォーマンスは良好です。ディスク読み取りの実行を開始する必要がある場合は、パフォーマンスがすぐに低下します。mykインスタンスのメモリ使用パターンを、3万行と3万行の2つのケースで実行していましたか?


これは問題により近いと思います。TBHは私が望むRインデックスです。他の空間数学は、古いシステムのAPIレイヤーで実行する必要があるため、素晴らしいボーナスです。私は少し調整を試みましたが、キーバッファーを増やすことは役に立ちませんでした(他のバッファーは、個人サーバーでの1テーブルクエリなので、テーブルバッファーのようにここでは役に立ちません)。奇妙なのは、クエリが実行されると、MySQLが私のマシンを地面に叩き込むことです(クエリの実行中に100%)。つまり、フルテーブルスキャンを実行するので、それほど奇妙ではないかもしれません
-andeyatz

5

mysqlのインストールまたは.ini設定に問題があるはずです。古いMac(10.6.8 / MySQL 5.2)で地理空間インデックスをテストしました。その構成はあなたのものに似ており、大きなジオデータダンプ(900万レコード)をテストしました。私はこのクエリをしました:

SET @radius = 30;
SET @center = GeomFromText('POINT(51.51359 7.465425)');
SET @r = @radius/69.1;
SET @bbox = CONCAT('POLYGON((', 
  X(@center) - @r, ' ', Y(@center) - @r, ',', 
  X(@center) + @r, ' ', Y(@center) - @r, ',', 
  X(@center) + @r, ' ', Y(@center) + @r, ',', 
  X(@center) - @r, ' ', Y(@center) + @r, ',', 
  X(@center) - @r, ' ', Y(@center) - @r, '))' 
);

SELECT geonameid, SQRT(POW( ABS( X(point) - X(@center)), 2) + POW( ABS(Y(point) - Y(@center)), 2 ))*69.1 
AS distance
FROM TABLENAME AS root
WHERE Intersects( point, GeomFromText(@bbox) ) 
AND SQRT(POW( ABS( X(point) - X(@center)), 2) + POW( ABS(Y(point) - Y(@center)), 2 )) < @r 
ORDER BY distance; 

わずか0.0336秒かかりました

上記のクエリを使用します。たとえば、@ centerのlat / lng値だけが取得されるテーブルに、city_latitude / city_longitudeと9-12 Mioからの単純なINDEXがあるテーブル間の比較に使用します。geonames.orgのテーブルには地理空間インデックスがあります。

そして、誰かがテーブルにビッグデータを挿入するときに、INSERTの後にインデックスを追加する方がパフォーマンスが向上する可能性があることを追加したかっただけです。そうでない場合は、追加する行ごとに時間がかかります... [しかし、それは重要ではありません]


うわーそれは本当に良いです。今、私は自分のテストで何が間違っていたのかわかりません。問題を引き起こしている可能性のあることの1つは、従来の地理空間データセットと比較したデータセットの性質です。それは私が推測しているだけで、これの根拠がないということです。速度を得るためにインデックスをメモリに強制する必要がないことは素晴らしいことです。
-andeyatz

半径のあるWHERE句は、インデックスの使用からテーブルのかなりの部分を除外する可能性があります。
-tmarthal

2

単一の2D列ではなく、2つの1D列に分割することを考えましたか?

オプティマイザーは、同様のすべてのデータを窒息させ、より多様性のある2つの列を用意すると役立つ場合があります。

また、チェックされるのは、アイテムがチェックされる順序です。Oracle Spatialで問題が発生し、姓とIN_REGIONフィルタで検索されました。オラクルは、最速の方法は姓を使用してから地域チェックを行うことであると判断しました。クリーブランドにあるすべてのロビンソンの地域チェックを行うのは遅いです。最初に空間インデックスを強制的に使用するには、Oracle固有の引数を渡さなければならなかったことを覚えています。


残念ながら、1つの次元は他の次元よりもはるかに少ない人口です。これを文脈にまとめると、ヒトゲノムには24のユニークな染色体(22のペアと2つの性染色体)があり、さまざまなレベルに集められたデータの袋があります。つまり、1つのディメンションで24個の一意の識別子のみである基本的なユースケースに要素をマッピングする場合です。当初の希望は、Rツリーインデックスが、よりパフォーマンスの高い重複範囲チェックを実行できるだけでなく、1つのクエリでこれらの領域を区別できるようになることでした。
アンデヤッツ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.