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

IBX, FIBPlus, UIB, ADO, .Net и прочее-прочее-прочее, в общем все, что относится к созданию приложений, работающих с InterBase, Firebird и Yaffil - клиент-серверных, трехзвенных, консольных и т.п.

Модератор: kdv

Ответить
vayer
Сообщения: 10
Зарегистрирован: 04 дек 2006, 08:57

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

Сообщение vayer » 04 дек 2006, 09:02

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

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 04 дек 2006, 10:01

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

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

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

Сообщение WildSery » 04 дек 2006, 11:14

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

vayer
Сообщения: 10
Зарегистрирован: 04 дек 2006, 08:57

Сообщение vayer » 05 дек 2006, 07:06

Вот часть кода:

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

  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, будет быстрее работать???

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 05 дек 2006, 09:43

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

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 05 дек 2006, 17:55

И инсёртного триггера заодно.

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 05 дек 2006, 19:13

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);

vayer
Сообщения: 10
Зарегистрирован: 04 дек 2006, 08:57

Сообщение vayer » 06 дек 2006, 04:30

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 - прироста скорости почти не было

vayer
Сообщения: 10
Зарегистрирован: 04 дек 2006, 08:57

Сообщение vayer » 06 дек 2006, 04:33

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, быстрее будет???

vayer
Сообщения: 10
Зарегистрирован: 04 дек 2006, 08:57

Сообщение vayer » 06 дек 2006, 04:34

Merlin писал(а):И инсёртного триггера заодно.
Тригера нет

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 06 дек 2006, 10:05

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

vayer
Сообщения: 10
Зарегистрирован: 04 дек 2006, 08:57

Сообщение vayer » 06 дек 2006, 10:42

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

vayer
Сообщения: 10
Зарегистрирован: 04 дек 2006, 08:57

Сообщение vayer » 06 дек 2006, 10:43

А как выполнить скрипт встроенными средствами на Delphi?

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 06 дек 2006, 11:31

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

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 06 дек 2006, 11:45

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

vayer
Сообщения: 10
Зарегистрирован: 04 дек 2006, 08:57

Сообщение vayer » 07 дек 2006, 04:47

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

vayer
Сообщения: 10
Зарегистрирован: 04 дек 2006, 08:57

Сообщение vayer » 07 дек 2006, 04:48

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

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 07 дек 2006, 10:01

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

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 07 дек 2006, 12:39

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

vayer
Сообщения: 10
Зарегистрирован: 04 дек 2006, 08:57

Сообщение vayer » 08 дек 2006, 05:57

Спасибо всем за помощь.
Перписал все через FIBPlus, ограничил цикл транзакцией - стало выполняться за 2 сек.

Ответить