Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Не пойму, почему долго работает следующий код [D7, FireBird 1.5.3]


Страницы:   1 2

pavel_guzhanov ©   (2007-05-02 08:47:00) 

 IBDSFil.SelectSQL.Clear;
 IBDSFil.SelectSQL.Add('select memb_id, fio, Card_ser, Card_no from Table1 where not fio like ('+'''%СОЛИДАРНЫЙ%'''+') order by memb_id');
 IBDSFil.Open;
//Этот запрос отрабатывает мгновенно и возвращает 50000 записей
 IBDSFil.FetchAll;
 Rec:=IBDSFil.RecordCount;
 PB.Min:=0;// прогрессбар
 PB.Max:=Rec;
 IBDSFil.First;
 while not IBDSFil.Eof do
 begin
   IBQRefSel.Close;
   IBQRefSel.Params[0].Value:=Filial_no;
   IBQRefSel.Params[1].Value:=IBDSFil.FieldByName('MEMB_ID').AsInteger;
   IBQRefSel.Open;
// это тоже отрабатывает моментально
   PB.Position:=PB.Position+1;
   if IBQRefsel.IsEmpty then // все 50000 записей удовлетворяют условию
   begin
     IBQRef.Close;
     IBTransaction2.Active:=true;
     IBQRef.Params[0].Value:=Filial_no;
     IBQRef.Params[1].Value:=IBDSFil.FieldByName('MEMB_ID').AsInteger;
     IBQRef.Params[2].Value:=IBDSFil.FieldByName('FIO').AsString;
     IBQRef.Params[3].Value:=IBDSFil.FieldByName('CARD_SER').AsString;
     IBQRef.Params[4].Value:=IBDSFil.FieldByName('Card_no').AsInteger;
     IBQRef.ExecSQL;
   end;
   IBDSFil.Next;
 end;
 IBTransaction2.Commit;
 ShowMessage('Загрузка завершена');


При работе получается 50000 записей. Они все в цикле грузятся в другую базу. Загрузка длится более 30 минут. Я пробовал активировать транзакцию на каждый инсерт, и в конце инсерта делал commit, пробовал все инсерты загружать одним commit'ом, пробовал делать 3000 инсертов в один commit, в любом случае загрузка идет более 30 минут. Подскажите пожалуйста, как можно оптимизировать этот участок кода?

PS Использую стандартные компоненты InterBase. База путая.

PPS Если начинаю грузить еще раз, т.е. не выполняется условие проверки, то, как это ни странно, работает еще медленнее, хотя в базу не пишется ничего. Может быть можно как-то по другому сделать проверку наличия записи в базе?


Sergey13   (2007-05-02 09:31:00) [21]

> [2] pavel_guzhanov ©   (02.05.07 09:10)
> Она тоже FireBird, находятся обе базы на одной машине

Через внешнюю таблицу можно попробовать, должно помочь.


ЮЮ   (2007-05-02 09:27:00) [22]

Без  FetchAll будет то же самое (закачка всех 50 000 записей), только растянутое по времени. Нужен серверный курсор, чтобы только одна запись тянулась на клиент.


> Она тоже FireBird, находятся обе базы на одной машине....

З.Ы. а FireBird гетерогенные запросы (одновременно к двум базам) не поддерживает? SQL cервер-то, надеюсь, один обе базы обслуживает?


Карелин Артем   (2007-05-02 09:18:00) [23]

1)
>    IBQRefSel.Close;
>    IBQRefSel.Params[0].Value:=Filial_no;
>    IBQRefSel.Params[1].Value:=IBDSFil.FieldByName('MEMB_ID').
> AsInteger;
>    IBQRefSel.Open;

записи тащатся на клиента. Избавиться надо от этого для ускорения.
2) Подготовка через Prepare 1 раз запросов даст некий прирост скорости.
3) >      IBQRef.Params[4]. Value:=IBDSFil.FieldByName('Card_no').
> AsInteger;

AsInteger тоже на Value замени.

Я бы сделал хранимую процедуру для вставки, в которой проверял бы проверку на существование перед вставкой


Sergey13   (2007-05-02 09:13:00) [24]

> [2] pavel_guzhanov ©   (02.05.07 09:10)
> то тогда каким образом подсчитать количесто записей

Запросом с count.


pavel_guzhanov   (2007-05-02 09:10:00) [25]


> В Table2 что ли? Или реально в другую БАЗУ?

В ДРУГУЮ БАЗУ... Она тоже FireBird, находятся обе базы на одной машине....

А насчет FetchAll посмотрю... Если из-за этого тормоза, то тогда каким образом подсчитать количесто записей, чтобы управлять прогрессбаром?


ЮЮ   (2007-05-02 09:06:00) [26]

> //Этот запрос отрабатывает мгновенно и возвращает 50000 записей

Зато в следующей строке   IBDSFil.FetchAll;эти 50 000 записей затаскиваются на клиента. Померяй-ка как долго он выполняется.


> Они все в цикле грузятся в другую базу.

В Table2 что ли? Или реально в другую БАЗУ?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо