Конференция "Базы" » Пакетная вставка большого набора данных [D7, Firebird]
 
  • GanibalLector © (11.11.16 13:15) [0]
    Данные постоянно приходят из разных потоков и возникают дикие задержки, если их писать в цикле:


    for I:=0 to TStrings(List.Items[0]).Count-1 do
     begin
       IBSQL1.SQL.Clear;
       IBSQL1.SQL.Add('INSERT INTO ...');
       ...
       IBSQL1.ParamByName('Поле').AsInteger:=0;
       IBSQL1.ExecQuery;
     end;



    Хочу попробовать пакетную вставку. В связи с этим вопрос, какие варианты существуют?
    Нашел следующий вариант:


    execute block as begin
    INSERT INTO Таблица VALUES (поля);
    INSERT INTO Таблица VALUES (поля);
    end



    Попробовал. Не совсем удобно. IBSQL может принять только 255 строк (почему?). Еще и вместо параметров нужно указывать реальные данные, предварительно их форматируя (дату, время).

    Какие еще альтернативы существуют?
    Спасибо!
  • Игорь Шевченко © (11.11.16 13:49) [1]

    > Какие еще альтернативы существуют?


    Еще существует использование параметров.

    Вместо

    for I:=0 to TStrings(List.Items[0]).Count-1 do
    begin
      IBSQL1.SQL.Clear;
      IBSQL1.SQL.Add('INSERT INTO ...');
      ...
      IBSQL1.ParamByName('Поле').AsInteger:=0;
      IBSQL1.ExecQuery;
    end;



    написать

    IBSQL1.SQL.Text := 'INSERT INTO ...';

    for I:=0 to TStrings(List.Items[0]).Count-1 do
    begin
      ...
      IBSQL1.ParamByName('Поле').AsInteger:=0;
      IBSQL1.ExecQuery;
    end;

  • iop © (11.11.16 13:50) [2]
    быстрый клиентский вариант один
    вместо тысячи отдельных строк передать серверу один блоб, и  делать инсерты по блобу на сервере.

    так как сервер "не настоящий",
    и там нет select from xml_type то будет нужен цикл разбора блоба и в нем инсерты.

    либо искать аналог чего-то вроде мускульного через серверный файл
    LOAD XML INFILE '/var/lib/mysql-files/input.xml' INTO TABLE mytable
  • GanibalLector © (11.11.16 14:13) [3]

    > быстрый клиентский вариант один
    > вместо тысячи отдельных строк передать серверу один блоб,
    >  и  делать инсерты по блобу на сервере.
    >
    > так как сервер "не настоящий",
    > и там нет select from xml_type то будет нужен цикл разбора
    > блоба и в нем инсерты.


    Где бы найти пример подобной реализации? Вы сами подобное реализовывали или это теория?
  • iop © (11.11.16 14:41) [4]
    вся "теория" это работа с текстовым блобом на сервере.

    сейчас тормозит потому что много инсертов с клиента.
    будет один запрос с блобом с клиента и много инсертов на сервере - будет быстро в разы разов.
  • GanibalLector © (11.11.16 14:52) [5]

    > вся "теория" это работа с текстовым блобом на сервере.


    Текстовый блоб это простой текстовый файл с разделителями?
    В хранимую процедуру я передаю этот файл (путь), а дальше его разбираю и выполняю. Так?
  • iop © (11.11.16 14:57) [6]
    в хранимую процедуру параметром передается тело файла, а не путь к файлу.
  • ухты_х © (11.11.16 15:29) [7]

    > Где бы найти пример подобной реализации? Вы сами подобное
    > реализовывали или это теория?

    тут что то похожее http://www.ibase.ru/xmldb/
  • stas © (12.11.16 07:14) [8]
    GanibalLector ©   (11.11.16 13:15)
    Странно СУБД на то и СУБД чтобы "разруливать" эти ситуации...
  • Вариант (12.11.16 07:52) [9]

    > GanibalLector ©   (11.11.16 13:15)

    Еще варианты:
    1 - Группировка данных и вставка группы  одной транзакцией. Например по накоплению N записей или истечению тайм-аута, если за заданный интервал не накопил нужное число записей. (пробовал сам такой вариант, ускоряет в разы.)

    2 - Создание пула потоков, которые работают с БД. Запросы делятся между потоками. У меня так сейчас работает порядка 15000 "клиентов" с одним сервером. У каждого потока своя очередь запросов.
  • Inovet © (12.11.16 11:48) [10]
    Вы тут какие-то пулы советуете, а автору надо хотя бы базовые вещи грамотно сделать. ИШ уже сказал в
    > [1] Игорь Шевченко ©   (11.11.16 13:49)

    Можно добавить ещё перед циклом
    IBSQL1.Prepare
    и после цикла, если надо
    IBSQL1.Unprepare
    до следующего раза. Почитать в общем о параметрах надо.
 
Конференция "Базы" » Пакетная вставка большого набора данных [D7, Firebird]
Есть новые Нет новых   [118232   +43][b:0][p:0.001]