Индексы и производительность - PullRequest
1 голос
/ 20 декабря 2011

Я новичок в Geotools и сталкиваюсь с этой проблемой: я добавляю в PostGis около 2 МБ информации о шейп-файле (около 5800 записей), и, что удивительно, это занимает более или менее 6 минут! Весьма раздражает, потому что мой «реальный» набор данных может быть до 25 МБ по группам шейп-файлов (shp, dbf ...), нужно 100 групп.

Мне сказали, что это может быть проблема с индексами, потому что Postgre обновляет индексы таблиц в каждой 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();

Спасибо за вашу помощь!


Итак, я проверил ваши решения, но больше мне ничего не помогло ... Время завершения осталось прежним. Вот мое определение таблицы:

  • серийный номер 10
  • the_geom геометрия 2147483647
  • xxx varchar 10
  • ххх int4 10
  • xxx varchar 3
  • xxx varchar 2
  • xxx float8 17
  • xxx float8 17
  • xxx float8 17

Так что я не думаю, что проблема напрямую связана с моим кодом или базой данных, возможно, это связано с системными ограничениями (ОЗУ, буферы ...). Я посмотрю на это в ближайшие несколько дней.

У вас есть еще идеи?

Ответы [ 2 ]

1 голос
/ 09 января 2012

Я вернулся с решением этой проблемы.После многих исследований я обнаружил, что проблема заключалась в физической сети: с локальной БД (приложение local to geotools) проблем не было.Сеть добавила 200 или 300 миллисекунд к каждому запросу оператора INSERT.С большим объемом данных, введенных в БД, пришло очень большое время отклика!

Так что никаких проблем с оригинальной конфигурацией Postgis или моим фрагментом кода ...

Спасибо всем за участие.

0 голосов
/ 20 декабря 2011

Вы можете проверить, являются ли индексы или ограничения 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 определено как deferrable (не по умолчанию):

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

EDIT:

Чтобы сузить причину проблемы, вы можете импортировать данные вместе с вашим приложением, создать дамп базы данных (с операторами вставки) и снова импортировать этот дамп базы данных. Это должно дать вам представление о том, сколько времени занимает простой импорт и каковы накладные расходы приложения.

Создайте дамп базы данных только для данных с операторами INSERT (операторы COPY будут быстрее, но ваше приложение также использует вставки, так что это лучше для сравнения):

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

Снова создайте пустую схему базы данных и импортируйте данные (с базовой синхронизацией):

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

Может быть, вы сможете немного лучше разобраться в проблеме с этим.

...