Вставка миллиона записей

Тема в разделе "SQL", создана пользователем AntonStarkov, 3 сен 2010.

  1. AntonStarkov

    AntonStarkov Гость

    Приветствую всех!
    Помогите решить задачку:

    Есть таблица около 150 атрибутов, один UNIQUE остальные нет. В ней около 50 миллионов записей. Нужно ее увеличить примерно в двое. Каким лучше способом это сделать? Insert в цикле, хотя я и не большой знаток, думаю будет очень, очень, очень долго.
    Поделитесь опытом :)
    Заранее спасибо!
     
  2. ????

    ???? Гость

  3. AntonStarkov

    AntonStarkov Гость

    >СУБД? Источник данных?

    Oracle. Данные произвольные, можно из этой же таблицы, только с уникальным одним полем.
     
  4. Aleksey

    Aleksey Гость

    1) Уникальное поле что из себя представляет? Это число или что-то другое?
    2) Сколько процессоров на сервере (или ядер)?

    Все зависит от размера таблицы, если бы не уникальность, то самое простое - это такой код:

    Код (Text):
    INSERT /*+ APPEND */ INTO tab1
    SELECT /*+ PARALLEL (t) */ *
    FROM tab1 t;

    COMMIT;
    Чтобы поддержать уникальность можно использовать триггер и последовательность, если таковых еще нет.
     
  5. ????

    ???? Гость

    самый быстрый способ - sql*loader, но надо иметь данные для импорта

    можно и на pl\sql используя bulk collect и forall
    [sql]DECLARE
    TYPE prod_tab IS TABLE OF products%ROWTYPE;
    products_tab prod_tab := prod_tab();
    BEGIN SELECT * BULK COLLECT INTO products_tab FROM products;

    FORALL i in products_tab.first .. products_tab.last
    INSERT INTO products VALUES products_tab(i);

    COMMIT;
    END;[/sql]
    в примере мы выбираем все данные из таблицы products и вставляем в неё же (удваиваем данные в таблице). если уникальное поле генерируется в триггере на основе сиквенса (или любым другим способом) - надо будет только подставить имя таблицы. иначе варианты :)

    ну а общеи рекомендации при вставке большого объема данных - удаление индексов и пересоздание после вставки и т.д.
     
  6. Aleksey

    Aleksey Гость

    Ничего быстрее SQL нет.

    Код (Text):
    INSERT /*+ APPEND */ INTO tab1
    SELECT /*+ PARALLEL (t) */ *
    FROM tab1 t;
    В этом SQL-коде процессы параллелятся и загрузка идет в режиме direct path минуя кэш буферов. Ничего быстрее не найдешь :)

    Указанный уважаемым ???? (в предыдущем посте) код PL/SQL, будет самым медленным, кроме того, в данном случае конструкция BULK COLLECT и FORALL мало того что гораздо медленней, но еще и повалится может, так как вся эта конструкция хранится в памяти сеанса (а это практически вся таблица):
    Код (Text):
    TYPE prod_tab IS TABLE OF products%ROWTYPE;
    products_tab prod_tab := prod_tab();
    Далее там же:
    Чтобы этот код работал нужно не только имя таблицы подставить, но и чтобы не было ограничения UNIQUE (так же, как и в моем INSERTe), так как вставка копии данных в таблицу не прокатит из-за нарушения целостности UNIQUE ключа.

    sql*loader - это крутое, но не самое быстрое средство, только его готовить надо дольше, чем сама заливка будет идти и при этом надо еще поиметь что лить. ;)
    Удаление и пересоздание индексов хорошо помогает, но только до тех пор, пока кусок данных, вставляемый в таблицу относительно размера самой таблицы достаточно велик. Это я к тому, что надо разумно подходить к удалению индексов.

    Я почему спросил, какое поле обеспечивает уникальность, если это число, то тут никаких триггеров не надо. Сначала узнаем максимальное значение в этом поле (или же изначально берем число, которое заведомо больше максимального значения уникального ключа):
    Код (Text):
    SELECT max(id) FROM tab;
    Затем полученное число используем в INSERTe - прибавляя его к существующим значениям ID (пусть у нас получился максимальный ID-шник 1000):
    Код (Text):
    INSERT /*+ APPEND */ INTO tab1
    SELECT /*+ PARALLEL (t) */
    id+1000, pole1,..., poleN
    FROM tab1 t;
    Тут больно будет в другом:
    Это значит, что надо будет все 150 полей перечислить в списке выбора оператора SELECT... ;)
     
Загрузка...
Похожие Темы - Вставка миллиона записей
  1. Dragon108
    Ответов:
    1
    Просмотров:
    471
  2. vitte
    Ответов:
    8
    Просмотров:
    728
  3. k85
    Ответов:
    2
    Просмотров:
    680
  4. lionk
    Ответов:
    6
    Просмотров:
    758
  5. sasha465
    Ответов:
    2
    Просмотров:
    1.368

Поделиться этой страницей