Конференция "Базы" » Странно зависает запрос. [D7, Firebird 1.54]
 
  • pavel_guzhanov © (19.11.08 12:06) [0]
    Вот такой запрос:
       IBQFil.Close;
       IBQFil.SQL.Clear;
       IBQFil.SQL.Add('select a.accn_id, a.accn_name, a.curr_state, a.status, c.Cont_type, a.open_date from accn a');
       IBQFil.SQL.Add('join cont c on c.cont_id=a.cont_id');
       IBQFil.SQL.Add('where a.memb_id=:m');



    далее в программе передаю параметр:

           
    IBQFil.Close;
    IBQFil.Params[0].AsInteger:=IBQRef.FieldByName('memb_id').AsInteger;
           S:=IBQFil.SQL.Text;
           IBQFil.Open;//<<<<<<<<<
           IBQFil.First;



    На помеченной строке программа зависает очень надолго (десятки минут)

    Если я на той же базе выполняю тот же запрос в IBExpert, передавая ему тот же параметр, то запрос выполняется мгновенно.

    Кроме того, в программе этот запрос выполняется в цикле, и зависает только при первой итерации цикла, в остальных итерациях тоже отрабатывает мгновенно. Я пробовал проделать это на двух разных базах (базы разных филиалов), получается тоже самое - первая итерация - зависание, последующие итерации - нормально.

    От чего может быть это зависание и как с ним бороться?
  • sniknik © (19.11.08 12:30) [1]
    в Firebird первый может тормозить из за начальной подгрузки dll, если например ембедед версия используется. сервер в принципе тоже время на "раскрутку"  может требовать, но десятки минут... это черезчур в обоих случаях, это у тебя в программе глюк.
  • Правильный$Вася (19.11.08 12:52) [2]
    автоматическая сборка мусора?
  • Сергей М. © (19.11.08 14:07) [3]

    > этот запрос выполняется в цикле


    Перед первой итерацией коннект с базой уже установлен ?
  • pavel_guzhanov © (19.11.08 15:05) [4]
    procedure TMainForm.BRefRemNPOClick(Sender: TObject);
    var ...
    begin
     puth:=GetCurrentDir;

     try
       if not IBDBRemContr.Connected then
       begin
         IBDBRef.DatabaseName:='localhost:'+puth+'\Users.fdb';
         IBDBRef.Params.Add('user_name=SYSDBA');
         IBDBRef.Params.Add('password=masterkey');
         IBDBRef.Connected:=true;
       end;
       IBQFil.Close;
       IBQFil.SQL.Clear;
       IBQFil.SQL.Add('select a.accn_id, a.accn_name, a.curr_state, a.status, c.Cont_type, a.open_date from accn a');
       IBQFil.SQL.Add('join cont c on c.cont_id=a.cont_id');
       IBQFil.SQL.Add('where a.memb_id=:m');

       for i:=1 to 28 do
       begin
         IBDBFil.Connected:=false;
         IBDBFil.DatabaseName:='localhost:'+Puth+'\npfe_'+IntToStr(i)+'.fdb';
         IBDBFil.Params.Add('user_name=SYSDBA');
         IBDBFil.Params.Add('password=masterkey');
         try
           IBDBFil.Connected:=true;
          except
           ShowMessage('Нет соединения с базой');
           continue;
         end;
         IBQKorpFlag.Close;
         IBQKorpFlag.Open;
         IBQRef.Close;
         IBQRef.SQL.Clear;
         IBQRef.SQL.Add('select count(*) as kol from users where filial_no=:f');
         IBQRef.Params[0].Value:=i;
         IBQRef.Open;
         PB3.Max:=IBQRef.FieldByName('kol').AsInteger;
         IBQRef.Close;
         IBQRef.SQL.Clear;
         IBQRef.SQL.Add('select id, memb_id from users where filial_no=:f');
         IBQRef.Params[0].Value:=i;
         IBQRef.Open;
         IBQRef.First;
         PB3.Position:=0;
         while not IBQRef.Eof do
         begin
           PB3.Position:=PB3.Position+1;
           IBQFil.Close;
           IBQFil.Params[0].AsInteger:=IBQRef.FieldByName('memb_id').AsInteger;
           S:=IBQFil.SQL.Text;
           IBQFil.Open; // здесь зависаем
           IBQFil.First;
           while not IBQFil.Eof do



    Вот полностью код процедуры до места зависания. Не вижу места для глюка :о)).

    Коннект с базой установлен, как видно из приведенного кода.
  • Правильный$Вася (19.11.08 15:44) [5]

    > for i:=1 to 28 do    begin      IBDBFil.Connected:=false;

    диковинная штука

    > PB3.Position:=0;
    IBQFil.Prepare;
    > while not IBQRef.Eof do
    >      begin
    >        PB3.Position:=PB3.Position+1;        IBQFil.Close;
    >         IBQFil.Params[0].AsInteger:=IBQRef.FieldByName('memb_id').
    > AsInteger;
  • pavel_guzhanov © (19.11.08 15:58) [6]

    > IBQFil.Prepare;


    Prepare действительно надо делать до передачи параметра запросу?
  • pavel_guzhanov © (19.11.08 16:10) [7]
    Теперь также точно виснет на IBQFil.Prepare;
  • pavel_guzhanov © (19.11.08 16:21) [8]
    База объемом 400 Мб, но BDQRef возвращает примерно 60 тысяч записей. Зависание при первой итерации цикла примерно 30 минут, при открытии IBQFil. IBQFil возвращает от 1 до десяти записей. База другого филиала, весит примерно 250 Мб, зависает при первой итерации примерно на 10 минут. Но баз у меня 28 штук, таких больших штук 8, остальные до 100 Мб.
  • pavel_guzhanov © (19.11.08 16:22) [9]

    >  но BDQRef возвращает

    пардон, IBQRef
  • Правильный$Вася (19.11.08 16:22) [10]

    > Prepare действительно надо делать до передачи параметра запросу?

    только тип параметра установи до этого

    > Теперь также точно виснет на IBQFil.Prepare;

    сборку мусора делал?
  • pavel_guzhanov © (19.11.08 16:25) [11]

    > сборку мусора делал?


    Пардон за глупый вопрос: а как?
  • Правильный$Вася (19.11.08 16:39) [12]

    > Пардон за глупый вопрос: а как?

    простейший способ - через gfix -sweep
  • pavel_guzhanov © (20.11.08 08:12) [13]
    Сделал, результат нулевой. Тоесть виснет также. Перед gfix сделал еще backup/restore...
  • StriderMan (20.11.08 15:32) [14]
    есть одна мысль. замечал такие тормоза, когда клиентская библиотека gds32.dll была от Interbase а сервер - firebird.

    IBQFil это TIBQuery?  попробуй на TIBSQL поменять, он легче и быстрее
  • atruhin © (20.11.08 15:54) [15]
    Приведи метаданные для accn, cont. И план запроса.
  • atruhin © (20.11.08 15:54) [16]
    Приведи метаданные для accn, cont. И план запроса.
  • PEAKTOP © (20.11.08 18:29) [17]
    Попробуй подконнектиться к базе из  Firebird 2.0 и выше и задать параметры транзакции
    isc_tpb_read_commited
    isc_tpb_write
    isc_tpb_rec_version
    isc_tpb_nowait
    Если глюк не вопроизведется, то батенька запустили Вы ваши базы данных. Backup-Retore им нуна срочно.

    Да, кстати, чуть не забыл

    ...............
    BDBFil.Connected:=false;
        IBDBFil.DatabaseName:='localhost:'+Puth+'\npfe_'+IntToStr(i)+'.fdb';
        IBDBFil.Params.Add('user_name=SYSDBA');
        IBDBFil.Params.Add('password=masterkey');
    ......


    Где чарсет подключения ?

        IBDBFil.Params.Add('lc_ctype=WIN1251');

  • Правильный$Вася (20.11.08 21:02) [18]

    > запустили Вы ваши базы данных. Backup-Retore им нуна срочно.

    ты невнимателен
    см [13]
  • pavel_guzhanov © (21.11.08 15:30) [19]
    Все решилось очень странным образом, я еще буду разбираться, что сие означает. Взял с сервера более свежие базы филиалов - и все заработало без проблем. На базах месячной давности все висло, несмотря на backup/restore и gfix -sweep
 
Конференция "Базы" » Странно зависает запрос. [D7, Firebird 1.54]
Есть новые Нет новых   [134477   +39][b:0][p:0.002]