Insert в Oracle
От: o_x_y  
Дата: 25.07.06 19:03
Оценка:
Доброе время суток.Передо мной вставала задача написать класс,который инсертит много(1000-10000) записей в таблицу Oracle.
Подскажите как лучше всего реализовать?
Re: Insert в Oracle
От: Trean Беларусь http://axamit.com/
Дата: 25.07.06 19:13
Оценка: 1 (1) +1
Здравствуйте, o_x_y, Вы писали:

__>Доброе время суток.Передо мной вставала задача написать класс,который инсертит много(1000-10000) записей в таблицу Oracle.

__>Подскажите как лучше всего реализовать?

http://java.sun.com/docs/books/tutorial/jdbc/jdbc2dot0/batchupdates.html

Оно?
Re[2]: Insert в Oracle
От: Sahivi  
Дата: 26.07.06 08:26
Оценка:
Здравствуйте, Trean, Вы писали:

T>Здравствуйте, o_x_y, Вы писали:


__>>Доброе время суток.Передо мной вставала задача написать класс,который инсертит много(1000-10000) записей в таблицу Oracle.

__>>Подскажите как лучше всего реализовать?

T>http://java.sun.com/docs/books/tutorial/jdbc/jdbc2dot0/batchupdates.html


T>Оно?


Есть такое мнение, что инсерт используя preparestatement тоже ускоряет данное действие, действительно ли это так? Если есть специались по Oracle — jdbc — java, то хочется услышать мнение, какой метод наиболее действенный, как лучше делать и почему

Заранее благодарен за ответ.
Re[3]: Insert в Oracle
От: ika Беларусь  
Дата: 26.07.06 09:08
Оценка:
Здравствуйте, Sahivi, Вы писали:
S>Есть такое мнение, что инсерт используя preparestatement тоже ускоряет данное действие, действительно ли это так? Если есть специались по Oracle — jdbc — java, то хочется услышать мнение, какой метод наиболее действенный, как лучше делать и почему
IMHO,
1) use batch updates
2) use prepared statemetns
3) disable indices before starting batch execution; enable them back at the finish.
Re[3]: Insert в Oracle
От: Igor Trofimov  
Дата: 26.07.06 09:10
Оценка:
Наиболее действенный — именно batch (array binding еще называется в Оракловой документации).
Потому что одним запросом на сервер отправляешь сразу кучу строк (скажем, 10 000).
Re[4]: Insert в Oracle
От: Sahivi  
Дата: 26.07.06 09:21
Оценка:
Здравствуйте, Igor Trofimov, Вы писали:

iT>Наиболее действенный — именно batch (array binding еще называется в Оракловой документации).

iT>Потому что одним запросом на сервер отправляешь сразу кучу строк (скажем, 10 000).


Нужно ли использовать prepareStatement или обычный Statement в коде? есть ли какой плюс от prepareStatement в данном случае?
Re[5]: Insert в Oracle
От: ika Беларусь  
Дата: 26.07.06 09:32
Оценка:
Здравствуйте, Sahivi, Вы писали:
S>Нужно ли использовать prepareStatement или обычный Statement в коде? есть ли какой плюс от prepareStatement в данном случае?
Нужно. Потому что в случае prepared statement сам запрос парсится компилируется только один раз, а затем используется многократно с разным набором параметров. А если просто statement — то разбор и компиляция будет проходить на каждом из 10000 (или сколько там?) инсертов.
Re[4]: Insert в Oracle
От: Sahivi  
Дата: 26.07.06 09:59
Оценка:
Здравствуйте, ika, Вы писали:

ika>Здравствуйте, Sahivi, Вы писали:

S>>Есть такое мнение, что инсерт используя preparestatement тоже ускоряет данное действие, действительно ли это так? Если есть специались по Oracle — jdbc — java, то хочется услышать мнение, какой метод наиболее действенный, как лучше делать и почему
ika>IMHO,
ika>1) use batch updates
ika>2) use prepared statemetns
ika>3) disable indices before starting batch execution; enable them back at the finish.


про 3 пункт можно поподробнее?
Re[5]: Insert в Oracle
От: ika Беларусь  
Дата: 26.07.06 10:08
Оценка:
Здравствуйте, Sahivi, Вы писали:
ika>>2) use prepared statemetns
ika>>3) disable indices before starting batch execution; enable them back at the finish.
S>про 3 пункт можно поподробнее?
Конечно можно. Есть таблица, в ней (весьма вероятно) пачка индексов. Когда вставляется запись, все они перестраиваются с учетом добавленной записи. Очевидно, что раз выгодней запустить такую перестройку только один раз вместо тысячи. Именно по этому я думаю и было бы полезно временно отключить индексы (или дропнуть вобще их). Когда они в конце даталоада будут восстановлены, они будут построены по последним даннгым, имеющимся в таблице.

ЗЫ: если на таблице есть триггеры, то отключать индексы нельзя (скорей всего перфоманс упадет, нужно смотреть что там за триггеры и что за индексы).

ЗЫ2: уменя нет точных метрик для сравнения. совет даю исключительно из интуитивных предположений и своих теоретичиских знаний.
Re[6]: Insert в Oracle
От: ika Беларусь  
Дата: 26.07.06 10:21
Оценка:
...добавлю: изыски типа отключения индексов не рекомендуется применять, если во время загрузки данных возможны параллельные обращения к таблице для чтения этих данных. Иначе каждый запрос при отсутствии индексов будет производить table full scan, что будет как сервер загружать зазря, так и работать медленно.
Re[6]: Insert в Oracle
От: Igor Trofimov  
Дата: 26.07.06 14:29
Оценка:
S>>Нужно ли использовать prepareStatement или обычный Statement в коде? есть ли какой плюс от prepareStatement в данном случае?

Протестируй. Но если у тебя всего тысяч сто записей — то может уже и не обязательно.

ika>Нужно. Потому что в случае prepared statement сам запрос парсится компилируется только один раз, а затем используется многократно с разным набором параметров. А если просто statement — то разбор и компиляция будет проходить на каждом из 10000 (или сколько там?) инсертов.


Мне кажется, в случае с array binding это неверно. Серверу достоверно известно, что нужно один и тот же sql-оператор выполнить над кучей параметров. Да еще как атомарное действие. С чего это он будет на каждый набор параметров перепарсивать запрос??? Очень сомнительно.
Re[7]: Insert в Oracle
От: stenkil  
Дата: 27.07.06 05:09
Оценка:
Здравствуйте, Igor Trofimov, Вы писали:

S>>>Нужно ли использовать prepareStatement или обычный Statement в коде? есть ли какой плюс от prepareStatement в данном случае?


iT>Протестируй. Но если у тебя всего тысяч сто записей — то может уже и не обязательно.


В свое время я проверял для выборки:
Выборка 4-х полей с 3-я параметрами из 1 000 000 записей
для Statement усредненное время 1-й выборки составило 30ms
для PreparedStatement на 1 ms меньше.
Понятно что данные относительны для конкретного компа, но тем не менее умножаем на 100 000 циклов и имеем конкретный ощутимый результат.

iT>Мне кажется, в случае с array binding это неверно. Серверу достоверно известно, что нужно один и тот же sql-оператор выполнить над кучей параметров. Да еще как атомарное действие. С чего это он будет на каждый набор параметров перепарсивать запрос??? Очень сомнительно.


Как раз для Prepared будет создаваться массив параметров запроса, а не массив запросов.
Re[8]: Insert в Oracle
От: Igor Trofimov  
Дата: 27.07.06 07:20
Оценка:
S>Понятно что данные относительны для конкретного компа

А еще — для конкретного запроса, структур данных, статистики, настроек оптимизатора
Для вставки все проще.

S>, но тем не менее умножаем на 100 000 циклов и имеем конкретный ощутимый результат.


Еще раз. Говорим про array binding. Один запрос на вставку сразу 10000 строк.
То есть если надо вставить 100 000, то умножай на 10 и получай лишних 10 ms
Re[9]: Insert в Oracle
От: stenkil  
Дата: 27.07.06 09:42
Оценка:
Здравствуйте, Igor Trofimov, Вы писали:

S>>Понятно что данные относительны для конкретного компа


iT>А еще — для конкретного запроса, структур данных, статистики, настроек оптимизатора

iT>Для вставки все проще.

S>>, но тем не менее умножаем на 100 000 циклов и имеем конкретный ощутимый результат.


iT>Еще раз. Говорим про array binding. Один запрос на вставку сразу 10000 строк.

iT>То есть если надо вставить 100 000, то умножай на 10 и получай лишних 10 ms

Протестировал для вставки: 10 000 записей в 4-е поля (int, double, String, Time)
Statement — 40 646 ms
Statement.addBatch — 14 439 ms
PreparedStatement — 34 660 ms
PreparedStatement.addBatch — 9 189 ms

addBatch c PreparedStatement предпочтительней
Re[10]: Insert в Oracle
От: Sahivi  
Дата: 27.07.06 13:10
Оценка:
Здравствуйте, stenkil, Вы писали:

S>Здравствуйте, Igor Trofimov, Вы писали:


S>>>Понятно что данные относительны для конкретного компа


iT>>А еще — для конкретного запроса, структур данных, статистики, настроек оптимизатора

iT>>Для вставки все проще.

S>>>, но тем не менее умножаем на 100 000 циклов и имеем конкретный ощутимый результат.


iT>>Еще раз. Говорим про array binding. Один запрос на вставку сразу 10000 строк.

iT>>То есть если надо вставить 100 000, то умножай на 10 и получай лишних 10 ms

S>Протестировал для вставки: 10 000 записей в 4-е поля (int, double, String, Time)

S> Statement — 40 646 ms
S> Statement.addBatch — 14 439 ms
S> PreparedStatement — 34 660 ms
S> PreparedStatement.addBatch — 9 189 ms

S>addBatch c PreparedStatement предпочтительней


Огромное спасибо, очень полезная инфа.

Скажите, пожалуйста, какой использовали драйвер, базу данных и настройки соединения?
Re[10]: Insert в Oracle
От: Sahivi  
Дата: 27.07.06 13:13
Оценка:
Здравствуйте, stenkil, Вы писали:

S>Здравствуйте, Igor Trofimov, Вы писали:


S>>>Понятно что данные относительны для конкретного компа


iT>>А еще — для конкретного запроса, структур данных, статистики, настроек оптимизатора

iT>>Для вставки все проще.

S>>>, но тем не менее умножаем на 100 000 циклов и имеем конкретный ощутимый результат.


iT>>Еще раз. Говорим про array binding. Один запрос на вставку сразу 10000 строк.

iT>>То есть если надо вставить 100 000, то умножай на 10 и получай лишних 10 ms

S>Протестировал для вставки: 10 000 записей в 4-е поля (int, double, String, Time)

S> Statement — 40 646 ms
S> Statement.addBatch — 14 439 ms
S> PreparedStatement — 34 660 ms
S> PreparedStatement.addBatch — 9 189 ms

S>addBatch c PreparedStatement предпочтительней


Быть может вы знаете ответ на такой вопрос — произошла ошибка на очередном инсерте, где настраивается дальнейшее поведение, инсертить ли остальные строки или откатит все или оставить только те что уже прошли? и можно ли вообще это настроить, как вывести в лог инсерт на котором произошла ошибка?
Re[11]: Insert в Oracle
От: ika Беларусь  
Дата: 27.07.06 13:22
Оценка:
Здравствуйте, Sahivi, Вы писали:
S>Быть может вы знаете ответ на такой вопрос — произошла ошибка на очередном инсерте, где настраивается дальнейшее поведение, инсертить ли остальные строки или откатит все или оставить только те что уже прошли? и можно ли вообще это настроить, как вывести в лог инсерт на котором произошла ошибка?
Не понял — в случай batch insert ошибка может случится только на всем пакете, но никак ни на отдельном инсерте. У вас точно batch? Вообще, ошибки в batch-операциях, согласно спецификации ЖДБЦ, возвращаются в виде массива целочисленных кодов-статусов в ответ на executeBatch(). А ошибка могла быть, как вариант, на достижении граничного объема транзакции.
Re[12]: Insert в Oracle
От: Sahivi  
Дата: 27.07.06 14:58
Оценка:
Здравствуйте, ika, Вы писали:

ika>Здравствуйте, Sahivi, Вы писали:

S>>Быть может вы знаете ответ на такой вопрос — произошла ошибка на очередном инсерте, где настраивается дальнейшее поведение, инсертить ли остальные строки или откатит все или оставить только те что уже прошли? и можно ли вообще это настроить, как вывести в лог инсерт на котором произошла ошибка?
ika>Не понял — в случай batch insert ошибка может случится только на всем пакете, но никак ни на отдельном инсерте. У вас точно batch? Вообще, ошибки в batch-операциях, согласно спецификации ЖДБЦ, возвращаются в виде массива целочисленных кодов-статусов в ответ на executeBatch(). А ошибка могла быть, как вариант, на достижении граничного объема транзакции.


да точно Batch просто необходимо уметь отлавливть какой инсерт допустим не прошел, к примеру может же быть такое что пробывал инсертиться непрвильный тип данных или символ какой запрещенный или там какое то стояло ограничение на таблице и оракл выдал ошибку, как поступает батч в этом случе он все данные откатывает или же удачно занесенные инсерты остаются?
Re[10]: Insert в Oracle
От: Igor Trofimov  
Дата: 27.07.06 16:03
Оценка:
S>Протестировал для вставки: 10 000 записей в 4-е поля (int, double, String, Time)
S> Statement — 40 646 ms
S> Statement.addBatch — 14 439 ms
S> PreparedStatement — 34 660 ms
S> PreparedStatement.addBatch — 9 189 ms
S>addBatch c PreparedStatement предпочтительней

14 секунд — это как-то очень много и 9 — тоже для вставки 10000 записей batch'ем... ИМХО.
И на prepare INSERT'а ушло 5 секунд??? На чем вы это пускали?

Можно увидеть код?
Re[11]: Insert в Oracle
От: stenkil  
Дата: 28.07.06 05:18
Оценка:
Здравствуйте, Igor Trofimov, Вы писали:


S>>Протестировал для вставки: 10 000 записей в 4-е поля (int, double, String, Time)

S>> Statement — 40 646 ms
S>> Statement.addBatch — 14 439 ms
S>> PreparedStatement — 34 660 ms
S>> PreparedStatement.addBatch — 9 189 ms
S>>addBatch c PreparedStatement предпочтительней

iT>14 секунд — это как-то очень много и 9 — тоже для вставки 10000 записей batch'ем... ИМХО.

iT>И на prepare INSERT'а ушло 5 секунд??? На чем вы это пускали?

iT>Можно увидеть код?


Celeron 2.4, RAM 248Mb, Win XP, FB Server: local host
Куда сбросить код?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.