Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> вставка в Оракл большого количество строк 
V
    Опции темы
cube
Дата 17.4.2015, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 11.4.2007

Репутация: 2
Всего: 3



Вставляю в таблицу базы данных Оракл большое количество строк, процесс занимает не много времени. Текстовый файл csv размером 400 мб, и 800 000 записей, загружается в бд, за 3 минуты.

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

К сожалению весь код привести не могу, но для понимания, процессы разделил на потоки. Один поток читает файл использует ArrayBlockingQueue (10000, false). 2 других производят вставку в таблицу. Каждый процесс коннекшен берет из пула, использует PreparedStatement и batch. Для чистоты эксперимента (чтобы понять какой процесс происходит дольше остальных), заменил метод put() на add() и увеличил размер очереди до 100 000, не проходит и 15 секунд как очередь переполняется и вываливается эксепшен.

Добавил еще 10 потоков для вставки в бд, всеравно вываливается эксепшен о переполнении очереди, заменил обратно add() на put() замерил время, с 10 потоками на вставку ушло еще на 2 минуты больше. Я понимаю что в этот системе узкое место вставка, но как ускорить ее? Свойства таблицы менять NOLOGGING задаю, никаких измененений в скорости не наблюдаю.

Код

public class Consumer extends Thread
{
    final static Logger log = StartPoint.getLogger();
    private int addedRows = 0;
    private int batchSize = 0;
    private BlockingQueue<Object[]> q;
    private String preparedSQL;
    
    private Connection conn;
    private PreparedStatement stmt;
    
    public Consumer(BlockingQueue<Object[]> q, Connection conn, String preparedSQL, int batchSize)
    {
        super();
        this.q = q;
        this.conn = conn;
        this.preparedSQL = preparedSQL;
        this.batchSize = batchSize;
    }
    
    @Override
    public void run() 
    {
        try {
            stmt = conn.prepareStatement(preparedSQL);
            Object[] data = new Object[0];
            int i = 0;
            while ((data = q.take()).length>0)
            {
                for ( i=0; i<data.length; i++)
                    stmt.setObject(i+1, data[i]);
                stmt.addBatch();
                if( ++addedRows % batchSize == 0)
                {
                    stmt.executeBatch();
                    stmt.clearBatch();      
                }
            }
            stmt.executeBatch();
            conn.commit();
            conn.close();
        } catch (Exception ex) {
            log.error("Can,t insert data to DB!", ex);
        }
    }
    public int getAddedRows(){return addedRows;}
}





Это сообщение отредактировал(а) cube - 17.4.2015, 14:58
PM MAIL   Вверх
LSD
Дата 17.4.2015, 18:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15709
Регистрация: 24.3.2004

Репутация: 209
Всего: 537



Скорее всего тут узкое место не Java а Oracle. На стороне Java достаточно батчинга. Запусти один поток и посмотри нагрузку CPU, если нагрузка на ядро со стороны Java не превышает 50%, то больше потоков не нужно. Если превышает, то можно попробовать добавить.
Со стороны Oracle надо смотреть, что у него там тупит, но скорее всего это IO.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
cube
Дата 19.4.2015, 19:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 11.4.2007

Репутация: 2
Всего: 3



да там загрузка 3,7% это смешно. IO имеете ввиду что? Вообще это база данных, к тому же очень шустрая. 
PM MAIL   Вверх
LSD
Дата 20.4.2015, 12:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15709
Регистрация: 24.3.2004

Репутация: 209
Всего: 537



Цитата(cube @  19.4.2015,  20:16 Найти цитируемый пост)
IO имеете ввиду что?

Запись на диск.


Цитата(cube @  19.4.2015,  20:16 Найти цитируемый пост)
Вообще это база данных, к тому же очень шустрая.

Иди к DBA пусть смотрит, что там тупит.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
AntonSaburov
Дата 20.4.2015, 17:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Штурман
****


Профиль
Группа: Модератор
Сообщений: 5658
Регистрация: 2.7.2002
Где: Санкт-Петербург

Репутация: 51
Всего: 118



1. Надо проверить как очищается таблица - если прямолинейно delete from table - то это может быть проблемой при большом числе записей.
2. Остальное LSD уже посоветовал - я тоже склоняюсь к тому, что здесь узкое место именно сам Оракл.
PM MAIL WWW ICQ   Вверх
cube
Дата 21.4.2015, 16:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 11.4.2007

Репутация: 2
Всего: 3



таблица перед загрузкой очищается sql запросом TRUNCATE TABLE, это достаточно быстрая процедура. Тем более что без commit'a.

есть идеи создавать временные таблицы, закидать быстренько туда, а уже потом процедурой на сервере зааппендить к реальной, как думаете в целом ускорит процесс? Возможности потерять данные велики?
PM MAIL   Вверх
LSD
Дата 21.4.2015, 18:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15709
Регистрация: 24.3.2004

Репутация: 209
Всего: 537



Цитата(cube @  21.4.2015,  17:07 Найти цитируемый пост)
есть идеи создавать временные таблицы, закидать быстренько туда, а уже потом процедурой на сервере зааппендить к реальной, как думаете в целом ускорит процесс?

Что значит "зааппендить"? Ты же truncate делаешь, она должна быть пустая.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
cube
Дата 22.4.2015, 09:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 11.4.2007

Репутация: 2
Всего: 3



имел ввиду hint /*+ APPEND */
Код


........ 
TRUNCATE TABLE MY_TABLE; 
........
INSERT /*+ APPEND */ INTO MY_TABLE.....    SELECT..... FROM MY_TMP_TABLE;
........
COMMIT;
........


сорри в pl/sql не силен
PM MAIL   Вверх
LSD
Дата 22.4.2015, 12:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15709
Регистрация: 24.3.2004

Репутация: 209
Всего: 537



Цитата(cube @  22.4.2015,  10:46 Найти цитируемый пост)
hint /*+ APPEND */

Стоит как минимум попробовать его использовать.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1348 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.