私は1年の3/4でPostgis 2.0を使用していますが、実際に使用している間は、クエリ処理に時間がかかりすぎて、ユースケースでは基本的に使用できなくなりました。
私は、多くの場合、数十万のマルチポリゴンを持つ地方自治体のデータセットで大量のジオプロセシングを行う傾向があります。これらのマルチポリゴンの形状は非常に不規則な場合があり、マルチポリゴンごとに4ポイントから78,000ポイントまで変化する可能性があります。
たとえば、525個のマルチポリゴンを含む管轄データセットで329,152個のマルチポリゴンとパーセルデータセットを交差させると、合計消費時間について次の統計が得られます。
ArcGIS 10.0 (on same host with windows 7 OS): 3 minutes
Postgis:56 minutes (not including geometry pre-processing queries)
言い換えると、ArcGISよりもPostgisでこの共通部分を実行するのに1500%長い時間が必要です。これは、私の最も単純なクエリの1つです。
ArcGISが高速に実行されると思われる理由の1つは、インデックスの改善によるものです。最近、一部のプログラマはこれらのインデックスがどのように機能するかを理解しました。Postgisでこれらのインデックスを作成する方法(またはインデックスを模倣するテーブルを作成する方法)を知っている人がいるかどうか疑問に思います。おそらくこれはPostgisの速度の問題のほとんどを解決するでしょう。特にArcGISは4 GBのRAMしか使用できませんが、postgisサーバーの最大4倍のRAMを使用できるため、何らかの方法が必要だと思います。
もちろん、postgisの動作が遅くなる理由はたくさんありますので、システム仕様の詳細バージョンを提供します。
Machine: Dell XPS 8300
Processor: i7-2600 CPU @ 3.40 GHz 3.40 GHz
Memory: Total Memory 16.0 GB (10.0 GB on virtual machine)
Platform: Ubuntu Server 12.04 Virtual Box VM
Potgres Version: 9.1.4
Postgis Version: POSTGIS="2.0.1 r9979" GEOS="3.3.5-CAPI-1.7.5" PROJ="Rel. 4.8.0, 6 March 2012" GDAL="GDAL 1.9.1, released 2012/05/15" LIBXML="2.7.8" LIBJSON="UNKNOWN" TOPOLOGY RASTER
また、VM自体の作成を含むpostgisのセットアップに使用したインストールプロセス全体の詳細を説明します。
また、confファイルで共有メモリをデフォルトの24MBから6 GBに増やし、次のコマンドを実行してpostgresを実行できるようにしました。
sudo sysctl -w kernel.shmmax=7516192768 (I know this setting is deleted every time you restart the OS)
sudo /etc/init.d/postgresql restart
私が知る限り、これはパフォーマンスの点で目立ったものはまったくありません。
このテストに使用したデータへのリンクは次のとおりです。
データを処理するために行った手順は次のとおりです。
ArcGIS
- データセットをArcMapに追加する
- 座標系を中央テキサスフィートに設定(srid 2277)
- ドロップダウンメニューから交差ツールを使用する
Postgis
次を使用して区画をインポートします。
shp2pgsql -c -s 2277 -D -i -I -W UTF-8 "tcad_parcels_06142012.shp" "public"."tcad_parcels_06142012" |psql -d postgis_testing -U postgres -h local_ip -p 5432
以下を使用して管轄区域をインポートします。
shp2pgsql -c -s 2277 -D -i -I -W UTF-8 "jurisdictions.shp" "public"."jurisdictions" |psql -d postgis_testing -U postgres -h local_ip -p 5432
区画内の無効なジオメトリを消去します。
DROP TABLE IF EXISTS valid_parcels;
CREATE TABLE valid_parcels(
gid serial PRIMARY KEY,
orig_gid integer,
geom geometry(multipolygon,2277)
);
CREATE INDEX ON valid_parcels USING gist (geom);
INSERT INTO valid_parcels(orig_gid,geom)
SELECT
gid
orig_gid,
st_multi(st_makevalid(geom))
FROM
tcad_parcels_06142012;
CLUSTER valid_parcels USING valid_parcels_geom_idx;
管轄区域の無効なジオメトリを消去します。
DROP TABLE IF EXISTS valid_jurisdictions;
CREATE TABLE valid_jurisdictions(
gid serial PRIMARY KEY,
orig_gid integer,
geom geometry(multipolygon,2277)
);
CREATE INDEX ON valid_jurisdictions USING gist (geom);
INSERT INTO valid_jurisdictions(orig_gid,geom)
SELECT
gid
orig_gid,
st_multi(st_makevalid(geom))
FROM
jurisdictions;
CLUSTER valid_jurisdictions USING valid_jurisdictions_geom_idx;
クラスターの実行:
cluster;
真空分析を実行します。
vacuum analyze;
クリーニングされたテーブルで交差を実行します。
CREATE TABLE parcel_jurisdictions(
gid serial primary key,
parcel_gid integer,
jurisdiction_gid integer,
isect_geom geometry(multipolygon,2277)
);
CREATE INDEX ON parcel_jurisdictions using gist (isect_geom);
INSERT INTO parcel_jurisdictions(parcel_gid,jurisdiction_gid,isect_geom)
SELECT
a.orig_gid parcel_gid,
b.orig_gid jurisdiction_gid,
st_multi(st_intersection(a.geom,b.geom))
FROM
valid_parcels a, valid_jurisdictions b
WHERE
st_intersects(a.geom,b.geom);
交差点の分析クエリの説明:
Total runtime: 3446860.731 ms
Index Cond: (geom && b.geom)
-> Index Scan using valid_parcels_geom_idx on valid_parcels a (cost=0.00..11.66 rows=2 width=1592) (actual time=0.030..4.596 rows=1366 loops=525)
-> Seq Scan on valid_jurisdictions b (cost=0.00..113.25 rows=525 width=22621) (actual time=0.009..0.755 rows=525 loops=1)
Nested Loop (cost=0.00..61428.74 rows=217501 width=24213) (actual time=2.625..3445946.889 rows=329152 loops=1)
Join Filter: _st_intersects(a.geom, b.geom)
私が読んだすべてのことから、私の交差クエリは効率的であり、クリーンなジオメトリでクエリに56分かかるために間違っていることはまったくわかりません!