2

私は Geotools を初めて使用し、この問題に直面しています。PostGis に約 2MB のシェープファイル情報 (約 5800 エントリ) を注入していますが、驚くべきことに、完了までに多かれ少なかれ 6 分かかります! 私の「実際の」データセットは、シェープファイルグループ(shp、dbf ...)ごとに最大25MBになる可能性があり、100グループが必要になるため、非常に面倒です。

Postgre は各 INSERT でテーブルのインデックスを更新するため、インデックスの問題である可能性があると言われました。一括 INSERT 中にこれらのインデックスを「無効」にして、最後にすべてのインデックスを作成するようにデータベースに指示する方法はありますか? または、それを行うより良い方法はありますか?

ここに私のコードスニペットがあります:

Map<String, Object> shpparams = new HashMap<String, Object>();
shpparams.put("url", "file://" + path);
FileDataStore shpStore = (FileDataStore) shpFactory.createDataStore(shpparams);
SimpleFeatureCollection features = shpStore.getFeatureSource().getFeatures();
if (schema == null) {
    // Copy schema and change name in order to refer to the same
    // global schema for all files
    SimpleFeatureType originalSchema = shpStore.getSchema();
    Name originalName = originalSchema.getName();
    NameImpl theName = new NameImpl(originalName.getNamespaceURI(), originalName.getSeparator(), POSTGIS_TABLENAME);
    schema = factory.createSimpleFeatureType(theName, originalSchema.getAttributeDescriptors(), originalSchema.getGeometryDescriptor(),
            originalSchema.isAbstract(), originalSchema.getRestrictions(), originalSchema.getSuper(), originalSchema.getDescription());
    pgStore.createSchema(schema);
}
// String typeName = shpStore.getTypeNames()[0];
SimpleFeatureStore featureStore = (SimpleFeatureStore) pgStore.getFeatureSource(POSTGIS_TABLENAME);

// Ajout des objets du shapefile dans la table PostGIS
DefaultTransaction transaction = new DefaultTransaction("create");
featureStore.setTransaction(transaction);
try {
    featureStore.addFeatures(features);
    transaction.commit();
} catch (Exception problem) {
    LOGGER.error(problem.getMessage(), problem);
    transaction.rollback();
} finally {
    transaction.close();
}
shpStore.dispose();

ご協力ありがとうございました!


だから私はあなたの解決策をテストしましたが、何も助けてくれませんでした...完了時間は同じです。これが私のテーブル定義です:

  • fid シリアル 10
  • the_geom ジオメトリ 2147483647
  • xxx varchar 10
  • xxx int4 10
  • xxx varchar 3
  • xxx varchar 2
  • xxx float8 17
  • xxx float8 17
  • xxx float8 17

したがって、問題が私のコードやデータベースに直接関係しているとは思いません。おそらくシステムの制限 (RAM、バッファーなど) が原因である可能性があります。これについては、今後数日のうちに見ていきます。

もっとアイデアはありますか?

4

2 に答える 2

1

この問題の解決策に戻ってきました。多くの調査の結果、物理ネットワークが問題であることがわかりました。ローカル DB (geotools アプリのローカル) では問題はありませんでした。ネットワークは、各 INSERT ステートメント要求に 200 または 300 ミリ秒を追加しました。DB に大量のデータが注入されたため、応答時間が非常に長くなりました。

したがって、元のPostgis構成または私のコードスニペットに問題はありません...

ご参加いただきありがとうございました。

于 2012-01-09T16:11:20.513 に答える
0

次の手順で、データベース内のインデックスまたはPK/FK制約が本当にボトルネックであるかどうかを確認できます。

1)データが単一のトランザクションに挿入されていることを確認します(自動コミットを無効にします)

2)すべてのインデックスを削除し、データのインポート後にそれらを再作成します(インデックスを無効にすることはできません)

DROP INDEX my_index;
CREATE INDEX my_index ON my_table (my_column);

3)PK / FK制約を削除または無効にし、データのインポート後にそれらを再作成または再度有効にします。データインポート中のPK/FK制約のチェックを、ドロップせずにスキップできます。

ALTER TABLE my_table DISABLE trigger ALL;
-- data import
ALTER TABLE my_table ENABLE trigger ALL;

このアプローチの欠点は、チェックが無効になっている間に挿入/更新されたデータについて、PK/FK制約がチェックされないことです。もちろん、PK / FK制約は、データのインポート後に既存のデータを再作成するときにも適用されます。

PK/FK制約のチェックをトランザクションの最後まで延期することもできます。これは、PK / FK制約が延期可能(デフォルトではない)として定義されている場合にのみ可能です。

ALTER TABLE my_table ADD PRIMARY KEY (id) DEFERRABLE INITIALLY DEFERRED;

START TRANSACTION;
-- data import
COMMIT; -- constraints are checked here

また

ALTER TABLE my_table ADD PRIMARY KEY (id) DEFERRABLE INITIALLY IMMEDIATE;

START TRANSACTION;
SET CONSTRAINTS ALL DEFERRED;
-- data import
COMMIT; -- constraints are checked here

編集:

問題の原因を絞り込むには、アプリケーションでデータをインポートし、(挿入ステートメントを使用して)データベースダンプを作成し、そのデータベースダンプを再度インポートします。これにより、プレーンインポートにかかる時間と、アプリケーションのオーバーヘッドがわかります。

ステートメントを使用してデータベースのデータのみのダンプを作成しますINSERTCOPYステートメントの方が高速ですが、アプリケーションでも挿入を使用するため、比較に適しています)。

pg_dump <database> --data-only --column-inserts -f data.sql

空のデータベーススキーマを再度作成し、データをインポートします(基本的なタイミングで)。

date; psql <database> --single-transaction -f data.sql > /dev/null; date

たぶん、これに関する問題についてもう少し洞察を得ることができます。

于 2011-12-20T19:50:01.873 に答える