Большие пакетные вставки: как получить SQL-код INSERT от Grails? - PullRequest
0 голосов
/ 17 июня 2011

У меня было много проблем с большими партиями вставок на Grails.Я испробовал все наиболее распространенные обходные пути, предложенные пользователями (например, WithTransaction и т. Д.), И вставки все еще были смехотворно медленными.

У меня есть пакет с примерно 500К объектов.В Gorm создание / вставка объекта в БД выполняется со скоростью около 200 мс на одну вставку, что, очевидно, недопустимо.Если я генерирую соответствующие операторы SQL INSERT из приложения в файле дампа, а затем запускаю файл дампа непосредственно в СУБД, я получаю <1 мс на вставку, что больше похоже на это.Чтобы сделать пакет в сети, я подумываю об этом решении (псевдо-Groovy-код): </p>

FileBuffer sqlFile = ...
largeBatch.each{
    def obj = createMyObject( it )
    String sql = getSQL code for obj insert
    sqlFile.write( sql )
}
execute sqlFile directly on JDBC

Как получить код вставки SQL из временного объекта?

Ответы [ 3 ]

0 голосов
/ 17 июня 2011

У Теда Нейлида есть хорошая запись об улучшении производительности пакетной вставки / обновления.Вы сталкивались с этим?Его предложения сработали для меня для пакетных обновлений.

Вот выдержка из статьи внизу:

Обычно сеанс grails hibernate выполняет что-то быстро и возвращает.Во время импорта мы выполняем тонну обработки, все с одним и тем же сеансом гибернации.Все эти объекты, которые обычно будут собираться мусором при закрытии сеанса, накапливаются.

Самый простой способ справиться с этим - создать простой метод периодической очистки этих коллекций.

Он предлагает периодически очищать и очищать сеанс.

data.eachWithIndex { datum, index ->
    // insert or update datum
    if(index % 100 == 0) {
        def session = sessionFactory.currentSession()
        session.flush()
        session.clear()
        // also clear the Grails domain class property instance map
        // - it may be that this isn't necessary anymore; not sure, but the article is
        //   a bit old, so maybe it's been fixed within Grails.
    }
}

Используя это, он улучшает пакетную вставку записей по 100 тыс. С ~ 2,5 часа до 3 минут.

@Тед - Если вы сталкиваетесь с этим вопросом / ответом и хотели бы повторить этот ответ самостоятельно, я был бы более чем счастлив удалить мой ответ и поднять ваш голос;Вы сделали всю тяжелую работу, выясняя это.Спасибо!

0 голосов
/ 17 июня 2011

Вы можете использовать пользовательский подкласс Hibernate Configuration для захвата SQL, который генерируется при запуске.Я не уверен, что лучший способ получить к нему доступ позже - возможно, публичное статическое поле в классе.

Вот код (поместите его в src / java):

package com.yourcompany.yourapp;

import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration;
import org.hibernate.HibernateException;

public class DdlCapturingConfiguration extends GrailsAnnotationConfiguration {

   @Override
   public String[] generateSchemaCreationScript(Dialect d) throws HibernateException {
      String[] sql = super.generateSchemaCreationScript(d);
      // do something with the sql
      return sql;
   }
}

, и вы зарегистрируете его в grails-app/conf/DataSource.groovy следующим образом:

dataSource {
   pooled = true
   driverClassName = ...
   username = ...
   password = ...
   dialect = ...
   configClass = com.yourcompany.yourapp.DdlCapturingConfiguration
}
0 голосов
/ 17 июня 2011

Существует 2 способа выполнить более быструю пакетную обработку для вставки данных:

  1. сеанс без состояния гибернации (http://docs.jboss.org/hibernate/core/3.3/reference/en/html/batch.html)
  2. собственный sql (http://groovy.codehaus.org/api/groovy/sql/Sql.html) (создать операторы x insert и запустить их вx транзакций базы данных), например, вы можете создать один отдельный дамп sql и запустить этот дамп в одной транзакции.

с сеансом без состояния гибернации вы также можете пакетно вставить вставки и вставить экземпляр класса домена, например сеанс.save (obj). с помощью navite sql вы должны создавать операторы самостоятельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...