0

1000以上のマーカー(Googleマップに配置する必要があります)を使用したマーカークラスタリングの問題に苦労しています。私は、すべてのマーカーを使用して大きな JSON 構造をレンダリングすることにあまり熱心ではありません。また、PostGIS を使用した複雑なサーバーの「地理」計算も好きではありません。

私が思いついた解決策は、世界地図をある種の階層空間ツリー、たとえばquad treeに分割することです。ここでは、データベースの各ポイントにそのツリーの「座標」が割り当てられます。これらの座標はon position_x index_of_tile in tier_x、「031232320012」などの文字列です。文字列の長さは、フロントエンド マップで有効になるズーム レベルの数によって異なります。基本的に、ユーザーがマップを移動またはズームした場合、現在のズーム レベルとビュー ポートの座標をパラメーターとして Ajax GET リクエストを起動します。次に、バックエンドで、「指定されたズーム レベルのビューポート」を指す文字列を作成する予定です。 .

編集:高速の GROUP BY も必要になります。SELECT count(*) from points GROUP BY left(coordinates, 5);

私の質問は、これらの操作をできるだけ速く実行する方法ですか? 私のデータベースは PostgreSQL です。

4

1 に答える 1

2

次に、バックエンドで、「指定されたズーム レベルのビューポート」を指す文字列を作成する予定です。 .

通常のインデックスは、インデックス付きの列の文字列の左端の 5 (または 6 または 7) 文字を見ている限り、最新の dbms で適切に機能するはずです。

SELECT ...
...
WHERE column_name LIKE '02113%';

PostgreSQL では、式でインデックスを作成することもできます。したがって、最初の 5 文字でインデックスを作成できます。

CREATE INDEX your_index_name ON your_table (left(column_name, 5));

そのようなインデックスが 3 つまたは 4 つある場合、PostgreSQL のクエリ オプティマイザーが適切なインデックスを選択することを期待しています。(5キャラ分、6キャラ分など)


テーブルを作成し、100 万行のランダム データを入力しました。

次のクエリでは、PostgreSQL のクエリ オプティマイザーが正しいインデックスを選択しました。

explain analyze
select s
from coords
where left(s, 5) ='12345';

0.1ミリ秒で戻ってきました。

また、GROUP BY を使用してテストしました。繰り返しになりますが、PostgreSQL のクエリ オプティマイザは正しいインデックスを選択しました。

"GroupAggregate  (cost=0.00..62783.15 rows=899423 width=8) (actual time=91.300..3096.788 rows=90 loops=1)"
"  ->  Index Scan using coords_left_idx1 on coords  (cost=0.00..46540.36 rows=1000000 width=8) (actual time=0.051..2915.265 rows=1000000 loops=1)"
"Total runtime: 3096.914 ms"

GROUP BY 句のような式left(name, 2)では、テーブルのすべての行ではないにしても、PostgreSQL がインデックスのすべての行にアクセスする必要があります。そのため、クエリに 3096 ミリ秒かかりました。インデックス内の 100 万行にアクセスする必要がありました。しかし、EXPLAIN プランから、インデックスを使用したことがわかります。

通常、地理アプリケーションでは PostGIS テーブルに対してバウンディング ボックスを使用して、アクセスする行数を減らすことを期待しています。クアッド ツリーの実装でそれ以上のことができない場合、私は PostGIS を使い続けて、その専門家になることができます。(ある程度の時間を費やすまで、その仕事ができないことは確かではありません。)

于 2013-04-23T17:05:21.543 に答える