Страница 1 из 1

Выполнение скрипта через dbexpress

Добавлено: 04 дек 2006, 09:02
vayer
Для набора записей в цикле вызываю хранимую процедуру, в качестве параметров которой передаю данные записей.
Ну очень медленно работает. Нельзя ускорить, например, через пакетную обработку либо выполнение скрипта (сохранить в файл, а затем выполнить скрипт) ???

Добавлено: 04 дек 2006, 10:01
kdv
без разницы - если ты медленно сделал, то будет что в скрипте, что через dbexpress, скорее всего. Если, конечно, ты после выполнения каждого оператора не перечитываешь наборы данных.

Re: Выполнение скрипта через dbexpress

Добавлено: 04 дек 2006, 11:14
WildSery
vayer писал(а):Нельзя ускорить, например,
Пока не увижу, что именно у тебя делается, и на какой версии сервера, не скажу.

Добавлено: 05 дек 2006, 07:06
vayer
Вот часть кода:

Код: Выделить всё

  with SQLProc do
  begin
    StoredProcName:='UPDATE_MENU_ITEM';
    Params.Clear;
    P1:=TParam.Create(Params,ptInput);
    P2:=TParam.Create(Params,ptInput);
    P3:=TParam.Create(Params,ptInput);
    P4:=TParam.Create(Params,ptInput);
    P5:=TParam.Create(Params,ptInput);
    P6:=TParam.Create(Params,ptInput);

    P1.Name:='ID';
    P2.Name:='NAME'; P2.Size:=40;
    P3.Name:='PRICE';
    P4.Name:='IS_GROUP';
    P5.Name:='UP_ID';
    P6.Name:='ID_PLACE';
    P6.asinteger:=DM.FirmId;
    SQLProc.Prepared:=true;    
  end;

  with dbxSHMenu do 
       //именно в этом цикле тормоз
       while not EOF do
       begin
          P1.asinteger:=FieldByName('id').asinteger;
          P2.asstring:=FieldByName('name').asstring;
          P3.asfloat:=FieldByName('price').asfloat;
          P4.asinteger:=FieldByName('is_group').asinteger;
          P5.asinteger:=FieldByName('up_id').asinteger;
          SQLProc.ExecProc; 
          Next;
       end;
Сервер - Firebird 1.5, подключаюсь по TCP

В хранимой процедуре, вызываемой в цикле, идет простой insert into.
Цикл перебирает порядка 2000 записей.
Пробовал убирать Foreign Keys из таблицы, куда происходит вставка, - прирост скорости есть, но незначительный (вместо 50 сек. - 40).

Если вместо dbexpress использовать FIBPlus, будет быстрее работать???

Добавлено: 05 дек 2006, 09:43
kdv
Если вместо dbexpress использовать FIBPlus, будет быстрее работать???
незначительно. покажи лучше код процедуры.

Добавлено: 05 дек 2006, 17:55
Merlin
И инсёртного триггера заодно.

Добавлено: 05 дек 2006, 19:13
WildSery
vayer писал(а):В хранимой процедуре, вызываемой в цикле, идет простой insert into.
Если простой INSERT, то почему процедура, а не

Код: Выделить всё

insert into Menu_Item (id, name, price, is_group, up_id, id_place)
  values (:id, :name, :price, :is_group, :up_id, :id_place);

Добавлено: 06 дек 2006, 04:30
vayer
kdv писал(а):
Если вместо dbexpress использовать FIBPlus, будет быстрее работать???
незначительно. покажи лучше код процедуры.

Код: Выделить всё

CREATE PROCEDURE UPDATE_MENU_ITEM (
    id integer,
    name varchar(40),
    price double precision,
    is_group integer,
    up_id integer,
    id_place integer)
as
declare variable aid integer;
begin
  /* Procedure Text */
  if (:is_group=1) then
   begin
     aid=0;
     select id from menu_groups where id=:id and id_place=:id_place into :aid;
     if (:aid>0) then
      begin
        update menu_groups
          set name=:name, up_id=:up_id, state=1
          where id=:id and id_place=:id_place;
      end
     else
      begin
        insert into menu_groups
           (id,id_place,name,up_id,state)
           values (:id,:id_place,:name,:up_id,1);
      end
   end
  else
   begin
     aid=0;
     select id from menu_items where id=:id and id_place=:id_place into :aid;
     if (:aid>0) then
      begin
        update menu_items
          set name=:name, price=:price, up_id=:up_id, state=1
          where id=:id and id_place=:id_place;
      end
     else
      begin
        insert into menu_items
           (id,id_place,name,price,up_id,state)
           values (:id,:id_place,:name,:price,:up_id,1);
      end
   end

  suspend;
пробовал убирать условия, оставлял просто insert - прироста скорости почти не было

Добавлено: 06 дек 2006, 04:33
vayer
WildSery писал(а):Если простой INSERT, то почему процедура, а не

Код: Выделить всё

insert into Menu_Item (id, name, price, is_group, up_id, id_place)
  values (:id, :name, :price, :is_group, :up_id, :id_place);
А что, если просто выполнять sql-оператор вроде insert'а через dbexpress, быстрее будет???

Добавлено: 06 дек 2006, 04:34
vayer
Merlin писал(а):И инсёртного триггера заодно.
Тригера нет

Добавлено: 06 дек 2006, 10:05
kdv
так. что-то я не вижу проблемы, по крайней мере с процедурой. впору товарищу профайлер на своей программе запускать. Или попробовать аналогичное на ibx написать, вдруг в dbexpress что-то не так.

Добавлено: 06 дек 2006, 10:42
vayer
kdv писал(а):так. что-то я не вижу проблемы, по крайней мере с процедурой. впору товарищу профайлер на своей программе запускать. Или попробовать аналогичное на ibx написать, вдруг в dbexpress что-то не так.
Зачем профайлер???? Уже проверял, тормозит именно в указанном цикле на вызове хранимой процедуры. Может, действительно, попробовать что-нибудь вроде FIBPlus? НО, где-то читал, что вообще-то не рекомендуется заниматься последовательной вставкой большого числа записей на interbase/firebird, а лучше это делать пакетной обработкой. Я так понимаю, через скрипт. Кстати, пробовал выполнить скрипт, соответствующий указанному циклу, в IBExpress - выполнился за 9 сек.!!!!

Добавлено: 06 дек 2006, 10:43
vayer
А как выполнить скрипт встроенными средствами на Delphi?

Добавлено: 06 дек 2006, 11:31
WildSery
Что-нибудь типа TIBScript.
А если сервер FB2, то можно в несколько execute block затолкать, будет ещё быстрее.

Добавлено: 06 дек 2006, 11:45
kdv
вполне возможно, что dbexpress ведет себя с транзакциями так же, как и BDE. т.е. при выполнении ХП пытается тут же сделать commit со всеми вытекающими. Потому я и советовал профайлер.
Значит, как минимум, надо бы указанный код обрамить стартом и коммитом транзакции, и посмотреть, не будет ли быстрее.

Добавлено: 07 дек 2006, 04:47
vayer
WildSery писал(а):Что-нибудь типа TIBScript.
А если сервер FB2, то можно в несколько execute block затолкать, будет ещё быстрее.
А можно подробнее про execute block, или, может быть, подскажите, где почитать про отличия FB2 от FB 1.5 и про перенос базы под FB2?

Добавлено: 07 дек 2006, 04:48
vayer
kdv писал(а):вполне возможно, что dbexpress ведет себя с транзакциями так же, как и BDE. т.е. при выполнении ХП пытается тут же сделать commit со всеми вытекающими. Потому я и советовал профайлер.
Значит, как минимум, надо бы указанный код обрамить стартом и коммитом транзакции, и посмотреть, не будет ли быстрее.
Скорее всего именно в этом дело, но как через dbexpress работать с транзакциями?

Добавлено: 07 дек 2006, 10:01
kdv
Скорее всего именно в этом дело, но как через dbexpress работать с транзакциями?
действительно, как же? Может быть, прочитать хелп? Или, прочитать
www.ibase.ru/devinfo/dbexpress.htm ?

Добавлено: 07 дек 2006, 12:39
WildSery
vayer писал(а):А можно подробнее про execute block, или, может быть, подскажите, где почитать про отличия FB2 от FB 1.5 и про перенос базы под FB2?
http://www.ibase.ru/firebird/Firebird_v ... eNotes.pdf

Добавлено: 08 дек 2006, 05:57
vayer
Спасибо всем за помощь.
Перписал все через FIBPlus, ограничил цикл транзакцией - стало выполняться за 2 сек.