массовая вставка из Java в Oracle - PullRequest
14 голосов
/ 27 апреля 2010

Мне нужно быстро вставить много маленьких строк в Oracle. (5 полей).

В MySQL я разбиваю вставки на группы по 100, а затем использую одну инструкцию вставки для каждой группы из 100 вставок.

Но с Oracle пользовательский отзыв заключается в том, что массовые вставки (где-то от 1000 до 30000) слишком медленные.

Есть ли подобный прием, который можно использовать для ускорения программных вставок из Java в Oracle?

Ответы [ 3 ]

10 голосов
/ 28 апреля 2010

Вы можете использовать модуль Spring DAO для пакетной вставки многих строк.

Пример, который вставляет коллекцию объектов Order в базу данных в одном обновлении:

public class OrderRepositoryImpl extends SimpleJdbcDaoSupport implements
        OrderRepository {

    private final String saveSql = "INSERT INTO orders(userid, username, coffee, coffeename, amount) "
            + "VALUES(?, ?, ?, ?, ?)";

    public void saveOrders(final Collection<Order> orders) {
        List<Object[]> ordersArgumentList = new ArrayList<Object[]>(orders
                .size());

        Object[] orderArguments;
        for (Order order : orders) {
            orderArguments = new Object[] { order.getUserId(),
                    order.getUserName(), order.getCoffe(),
                    order.getCoffeeName(), order.getAmount() };

            ordersArgumentList.add(orderArguments);
        }

        getSimpleJdbcTemplate().batchUpdate(saveSql, ordersArgumentList);
    }
}
2 голосов
/ 27 апреля 2010

Вы не знаете, как передавать эти записи в базу данных. Наилучшим способом является использование массива, поскольку это позволяет использовать множество изящных массовых операций FORALL в Oracle.

В этом примере пакета есть две процедуры. Одна, которая заполняет коллекцию записей T23 (таблица, которая содержит пять числовых столбцов), а другая, которая массово вставляет записи в эту таблицу, используя массив.

SQL> create or replace package p23 as
  2      type t23_nt is table of t23%rowtype;
  3      function pop_array ( p_no in number )
  4          return t23_nt;
  5      procedure ins_table ( p_array in t23_nt );
  6  end p23;
  7  /

Package created.

SQL> create or replace package body p23 as
  2
  3      function pop_array ( p_no in number )
  4          return t23_nt
  5      is
  6          return_value t23_nt;
  7      begin
  8          select level,level,level,level,level
  9          bulk collect into return_value
 10          from dual
 11          connect by level <= p_no;
 12          return return_value;
 13      end pop_array;
 14
 15      procedure ins_table
 16              ( p_array in t23_nt )
 17      is
 18          s_time pls_integer;
 19      begin
 20
 21          s_time := dbms_utility.get_time;
 22
 23          forall r in p_array.first()..p_array.last()
 24              insert into t23
 25              values p_array(r);
 26
 27          dbms_output.put_line('loaded '
 28                  ||to_char(p_array.count())||' recs in '
 29                  ||to_char(dbms_utility.get_time - s_time)
 30                  ||' csecs');
 31      end ins_table;
 32  end p23;
 33  /

Package body created.

SQL>

Вот вывод некоторых пробных прогонов:

SQL> declare
  2      l_array p23.t23_nt;
  3  begin
  4      l_array := p23.pop_array(500);
  5      p23.ins_table(l_array);
  6      l_array := p23.pop_array(1000);
  7      p23.ins_table(l_array);
  8      l_array := p23.pop_array(2500);
  9      p23.ins_table(l_array);
 10      l_array := p23.pop_array(5000);
 11      p23.ins_table(l_array);
 12      l_array := p23.pop_array(10000);
 13      p23.ins_table(l_array);
 14      l_array := p23.pop_array(100000);
 15      p23.ins_table(l_array);
 16  end;
 17  /
loaded 500 recs in 0 csecs
loaded 1000 recs in 0 csecs
loaded 2500 recs in 0 csecs
loaded 5000 recs in 1 csecs
loaded 10000 recs in 1 csecs
loaded 100000 recs in 15 csecs

PL/SQL procedure successfully completed.

SQL>
SQL> select count(*) from t23
  2  /

  COUNT(*)
----------
    119000

SQL>

Я думаю, что вставка 100 000 записей за 0,15 секунды должна понравиться всем, кроме самых требовательных пользователей. Итак, вопрос в том, как вы подходите к своим вставкам?

0 голосов
/ 27 апреля 2010

В настоящее время MySQL - это Oracle, поэтому, возможно, более простым решением было бы остаться на MySQL ...

Если нет, то перед запуском группы вставок убедитесь, что транзакция запущена, после ее завершения зафиксируйте транзакцию и начните новую транзакцию для следующей группы вставок.

Также проверьте наличие ненужных определений индекса, которые могут замедлять время вставки.

Обновлен ...
Массовая вставка относится к последнему шагу ETL (Извлечение нагрузки преобразования), поэтому вы рассматривали возможность использования инструмента ETL на основе Java, такого как pentaho kettle или talend-studio .

Pentaho описывает свои средства массовой загрузки Oracle здесь .

Быстрый Google также показывает некоторые предварительные доказательства того, что Talend также имеет некоторую поддержку массовой загрузки Oracle.

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