4

バックグラウンド:

次のデータをデータベースに保存する必要があります。

  • タグ付きのosmノード;

  • 重み付きの osm エッジ (.osm ファイルの「way」から抽出された 2 つのノード間のエッジ)。

同じ 'way' セットにあるエッジを形成するノードは、これらのウェイと同じタグを持つ必要があります。つまり、ハイウェイであるノードの 'way' セット内のすべてのノードは 'highway' タグを持つ必要があります。

さまざまなフィルターに基づいてグラフを簡単に生成するには、この構造が必要です。たとえば、高速道路であるノードとエッジのみで構成されるグラフ、または「歩道」グラフなどです。

問題:

以前に空間インデックスについて聞いたことがなかったので、.osm ファイルを MySQL データベースに解析しました。

  • 「ノード」テーブルへのすべてのノード(それぞれの座標列を含む)-OK、私の場合は約9,000,000行:

(INSERT INTO nodes VALUES [pseudocode]node_id,lat,lon[/pseudocode];

  • 「エッジ」テーブルへのすべての方法 (通常、1 つの方法でいくつかのエッジが作成されます) - OK、約 9,000,000 行も同様に:

(INSERT INTO edges VALUES [pseudocode]edge_id,from_node_id,to_node_id[/pseudocode];

  • ノードにタグを追加し、エッジの重みを計算する -問題:

問題のあるphpスクリプトは次のとおりです。

$query = mysql_query('SELECT * FROM edges');
$i=0;
while ($res = mysql_fetch_object($query))  {
$i++;
echo "$i\n";
$node1 = mysql_query('SELECT * FROM nodes WHERE id='.$res->from);
$node1 = mysql_fetch_object($node1);
$tag1 = $node1->tags;
$node2 = mysql_query('SELECT * FROM nodes WHERE id='.$res->to);
$node2 = mysql_fetch_object($node2);
$tag2 = $node2->tags;

mysql_query('UPDATE nodes SET tags="'.$tag1.$res->tags.'" WHERE nodes.id='.$res->from);
mysql_query('UPDATE nodes SET tags="'.$tag2.$res->tags.'" WHERE nodes.id='.$res->to);`

Nohup は、55 ~ 60 秒ごとに 'echo "$i\n"' の出力を表示します (私の場合のように、'edges' テーブルのサイズが 9,000,000 行を超える場合、完了するまでに 17 年以上かかることがあります)。

Htop は、CPU の 40 ~ 60% を使用する /usr/bin/mysqld プロセスを示しています。

エッジの重み (距離) を計算しようとするスクリプトにも同じ問題が存在します (すべてのエッジを選択し、エッジを取得し、「ノード」テーブルからこのエッジの 2 つのノードを選択し、距離を計算し、エッジ テーブル)。

質問:

この SQL 更新を高速化するにはどうすればよいですか? MySQL の構成設定を微調整する必要がありますか? または、PostGIS 拡張機能を備えた PostgreSQL を使用する必要がありますか? データに別の構造を使用する必要がありますか? それとも、何らかの形で空間インデックスを利用する必要がありますか?

4

2 に答える 2

3

PostgreSQL
Openstreetmap自体はPostgreSQLを使用しているので、それが推奨されると思います。
参照:http ://wiki.openstreetmap.org/wiki/PostgreSQL

OSMのデータベーススキーマは次の場所で確認できます:http ://wiki.openstreetmap.org/wiki/Database_Schema

したがって、OSMが最大の互換性のために使用するのと同じフィールド、フィールドタイプ、およびインデックスを使用できます。

MySQL
.osmファイルをMySQLデータベースにインポートする場合は、次を参照して
ください。http
://wiki.openstreetmap.org/wiki/OsmDB.pm ここに、MySQLテーブルを作成し、OSMファイルを解析するperlコードがあります。それをMySQLデータベースにインポートします。

高速化
一括更新する場合は、更新のたびにインデックスを更新する必要はありません。
インデックスを無効にし、すべての更新を実行して、インデックスを再度有効にすることができます。
私はそれがずっと速くなるはずだと推測しています。

幸運を

于 2011-04-24T21:20:09.580 に答える
3

私があなたの言うことを正しく理解していれば、議論すべきことが 2 つあります。

まず、ハイウェイタグを開始ノードと停止ノードに配置するというアイデア。ノードには複数のエッジを接続できますが、2 番目のエッジからタグを配置する場所は? 交差点の場合は 3 番目か 4 番目でしょうか。そもそもハイウェイ タグがエッジ テーブルに配置されている理由は、それが属している関係の観点からです。

次に、テーブル全体を取得してデータベースの外部で処理することは正しい方法ではありません。リレーショナル データベースが本当に得意とすることは、このプロセス全体を処理することです。

私は mysql を使ったことがありませんが、PostGIS には空間機能がはるかに優れているため (この特定のタスクに空間機能が必要ない場合でも)、PostGIS に移行するとおそらくもっと楽しくなることに完全に同意します。私が聞いたことがある。

したがって、最初の問題を無視して、概念を示すためだけに、1 つのノードに接続されているエッジは 2 つしかなく、各ノードには 2 つのタグ フィールドがあるとします。タグ 1 とタグ 2。次に、PostGIS では次のようになります。

UPDATE nodes set tag1=edges.tags from edges where nodes.id=edges.from;
UPDATE nodes set tag2=edges.tags from edges where nodes.id=edges.to;

インデックスを無効にすると、非常に高速になります。

繰り返しますが、私があなたを正しく理解していれば。

于 2011-04-29T07:12:29.097 に答える