Таблица Hash кластера Oracle с более быстрой вставкой - PullRequest
1 голос
/ 13 декабря 2008

Поскольку я начал процесс вставки 7M строк из одной таблицы в две другие, мне интересно, есть ли более быстрый способ сделать это. Ожидается, что процесс завершится через час, это 24 часа обработки.

Вот как это происходит:

Данные из этой таблицы

RAW (word VARCHAR2(4000), doc VARCHAR2(4000), count NUMBER);

должен найти новый дом в двух других таблицах кластера T1 и T2

CREATE CLUSTER C1 (word VARCHAR2(4000)) SIZE 200 HASHKEYS 10000000;
CREATE CLUSTER C2 (doc VARCHAR2(4000)) SIZE 200 HASHKEYS 10000000;

T1 (word VARCHAR2(4000), doc VARCHAR2(4000), count NUMBER) CLUSTER C1(word);
T2 (doc VARCHAR2(4000), word VARCHAR2(4000), count NUMBER) CLUSTER C2(doc);

через вставки Java с ручной фиксацией, подобной этой

stmtT1 = conn.prepareStatement("insert into T1 values(?,?,?)");
stmtT2 = conn.prepareStatement("insert into T2 values(?,?,?)");

rs = stmt.executeQuery("select word, doc, count from RAW");

conn.setAutoCommit(false);

while (rs.next()) {
    word = rs.getString(1);
    doc = rs.getString(2);
    count = rs.getInt(3);

    if (commitCount++==10000) { conn.commit(); commitCount=0; }

    stmtT1.setString(1, word);
    stmtT1.setString(2, doc);
    stmtT1.setInt(3, count);

    stmtT2.setString(1, doc);
    stmtT2.setString(2, word);
    stmtT2.setInt(3,count);

    stmtT1.execute();
    stmtT2.execute();
}

conn.commit();

Есть идеи?

Ответы [ 4 ]

3 голосов
/ 13 декабря 2008

Первое, что я бы порекомендовал, это сделать простой оператор вставки-выбора и позволить базе данных обрабатывать все перемещения данных. Не очень полезно, если вы перемещаете данные между двумя компьютерами или если у вас недостаточно сегментов отката, достаточных для обработки всего запроса.

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

В-третьих, если у вас уже нет большого количества строк в таблицах назначения, нужно отбросить все индексы перед вашими вставками и воссоздать после. Если вы оставите индексы на месте, они должны будут обновляться для каждой строки, добавляя к заголовку «грязного» блока.

И наконец: вам нужны кластерные таблицы? По моему опыту, они не покупают вас много (предостережение: этот опыт был на одном табличном пространстве).

1 голос
/ 15 декабря 2008

Ну, вы не можете вызвать таблицу RAW в Oracle - это зарезервированное слово, поэтому будет возникать ошибка ORA-00903.

Кроме этого, вы бы использовали:

insert all
into t1
into t2
select * from RAW
/

«Ряд за строкой - медленно-медленно»:)

0 голосов
/ 05 января 2009

Концептуально аналогично addBatch, вы могли бы написать процедуру PL / SQL, которая принимает массивы (word, doc, count) и обрабатывает вставки на стороне сервера. Концептуально это похоже, поскольку вы сокращаете количество сетевых поездок, отправляя несколько записей за один раз, и вы можете добиться более высокой производительности. С другой стороны, он более сложный и хрупкий, поскольку требует написания PL / SQL на стороне сервера и потребует дополнительной логики массивов на стороне клиента. В Oracle TechNet есть несколько примеров этого.

// Николай

0 голосов
/ 14 декабря 2008

Если у вас нет особых причин обрабатывать данные в приложении, Я бы пошел на прямой ВСТАВИТЬ КАК ВЫБРАТЬ. Использование Parallel DML может дать вам огромную разницу.

Проверьте также INSERT ALL синтаксис (1 чтение для 2 записей), если это соответствует вашим потребностям.

Если у вас проблемы с вводом-выводом, 1ч должно быть более чем достаточно ...

Привет

...