Импорт большого обьема - жуткие тормоза

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Ответить
Ugrael
Сообщения: 23
Зарегистрирован: 10 окт 2005, 12:16

Импорт большого обьема - жуткие тормоза

Сообщение Ugrael » 30 ноя 2005, 10:18

Доброго времени суток.
Есть такакя проблема-есть база. сней работают 2 человека.
они паралельно делают либо импорт из dbf файла либо печать множества записей. Так вот когда начинается импорт или печать то база словно переходит в однопользовательский режим. пока не пройдет печать или импорт другой человек вообще не может вводить\печатать записи. Люди жалуются и вообщем то справедливо.
как это делается. Одна database, одна транзакция (read commited). несколько dataset-ов. Импорт идет в отдельную таблицу, где записи обрабатываются и потом переносятся в главную таблицу. печать идет сразу из главной. прошу помощи.спасибо.

ZMan
Сообщения: 18
Зарегистрирован: 08 сен 2005, 07:44

Re: Импорт большого обьема - жуткие тормоза

Сообщение ZMan » 30 ноя 2005, 10:25

Ugrael писал(а):Так вот когда начинается импорт или печать то база словно переходит в однопользовательский режим. пока не пройдет печать или импорт другой человек вообще не может вводить\печатать записи.
Опиши подробнее, как проделываешь импорт?

Ugrael
Сообщения: 23
Зарегистрирован: 10 окт 2005, 12:16

Re: Импорт большого обьема - жуткие тормоза

Сообщение Ugrael » 30 ноя 2005, 10:43

ZMan писал(а):Опиши подробнее, как проделываешь импорт?
импорт из dbf файла в цикле построчно.
то бишь insertrecord(...), next

ZMan
Сообщения: 18
Зарегистрирован: 08 сен 2005, 07:44

Re: Импорт большого обьема - жуткие тормоза

Сообщение ZMan » 30 ноя 2005, 11:40

Ugrael писал(а):
ZMan писал(а):Опиши подробнее, как проделываешь импорт?
импорт из dbf файла в цикле построчно.
то бишь insertrecord(...), next
Мало информации. Желательно полностью код как ты это дело вытягиваешь и записываешь.

Ugrael
Сообщения: 23
Зарегистрирован: 10 окт 2005, 12:16

Re: Импорт большого обьема - жуткие тормоза

Сообщение Ugrael » 30 ноя 2005, 11:46

DataModule1.importdbf.First;
for i:=1 to DataModule1.importdbf.RecordCount do
begin
DataModule1.NolDataSet.Insert;
DataModule1.NolDataSet.FieldByName('fam').AsString:=DataModule1.importdbf.FieldByName('fam').AsString;
DataModule1.NolDataSet.FieldByName('imq').AsString:=DataModule1.importdbf.FieldByName('imq').AsString;
DataModule1.NolDataSet.FieldByName('otc').AsString:=DataModule1.importdbf.FieldByName('otc').AsString;
DataModule1.NolDataSet.FieldByName('DATA_R').AsString:=DataModule1.importdbf.FieldByName('DATA_R').AsString;
DataModule1.NolDataSet.Post;
oper.glavTransaction.Commit;
DataModule1.NolDataSet.Active:=true;
DataModule1.importdbf.Next;
end;


Вот так. Только полей конечно больше ( 20 )

Ugrael
Сообщения: 23
Зарегистрирован: 10 окт 2005, 12:16

Re: Импорт большого обьема - жуткие тормоза

Сообщение Ugrael » 30 ноя 2005, 11:47

DataModule1.importdbf.First;
for i:=1 to DataModule1.importdbf.RecordCount do
begin
DataModule1.NolDataSet.Insert;
DataModule1.NolDataSet.FieldByName('fam').AsString:=DataModule1.importdbf.FieldByName('fam').AsString;
DataModule1.NolDataSet.FieldByName('imq').AsString:=DataModule1.importdbf.FieldByName('imq').AsString;
DataModule1.NolDataSet.FieldByName('otc').AsString:=DataModule1.importdbf.FieldByName('otc').AsString;
DataModule1.NolDataSet.FieldByName('DATA_R').AsString:=DataModule1.importdbf.FieldByName('DATA_R').AsString;
DataModule1.NolDataSet.Post;
oper.glavTransaction.Commit;
DataModule1.NolDataSet.Active:=true;
DataModule1.importdbf.Next;
end;


Вот так. Только полей конечно больше ( 20 )

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

Сообщение kdv » 30 ноя 2005, 12:11

судя по всему, ты не читал ни www.ibase.ru/devinfo/ibx.htm ни
www.ibase.ru/devinfo/impexp.htm

т.к. вставлять в базу таким способом - dataset.insert/post , да еще делать commit каждый раз, это самый худший способ, который можно придумать.

ZMan
Сообщения: 18
Зарегистрирован: 08 сен 2005, 07:44

Re: Импорт большого обьема - жуткие тормоза

Сообщение ZMan » 30 ноя 2005, 12:32

Ugrael писал(а): for i:=1 to DataModule1.importdbf.RecordCount do
begin
DataModule1.NolDataSet.Insert;
...
DataModule1.NolDataSet.Post;
oper.glavTransaction.Commit;
...
end;
Во-первых, так делать нельзя! Commit делается после вставки минимум 200 записей, тем более dbf.
Ugrael писал(а):DataModule1.importdbf.First;
for i:=1 to DataModule1.importdbf.RecordCount do
begin
...
oper.glavTransaction.Commit;
DataModule1.NolDataSet.Active:=true;
DataModule1.importdbf.Next;
end;
Во-вторых, сам логически подумай, что ты делаешь?
1. становишься на первую запись;
2. в циксе комитешь базу;
3. после комита становишься на след. запись. После какой записи?!
Ответ: всегда после первой.

Я, вообще, не в понятках! Как, вообще, завершается такой цикл???! :shock: :?:


Решение:
1. Вынеси комит из цикла и удали строчку
...
DataModule1.NolDataSet.Active:=true;
...
А. вообще, когда нужно заинсертить записи, я делаю так

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

First
while not EOF do
begin
  SQL.Text:='insert into Table (Field1, Field2,...,FieldN) values (:Param1, :Param2,...,:ParamN)';
  for i:= 0 to Params.Count-1 do
   begin
     Params[i].AsVariant:=ValueN; //где ValueN - любой источник данных(запрос, массив и тд и др)
   end
  Next;
end;
Commit; //если нужен

Ugrael
Сообщения: 23
Зарегистрирован: 10 окт 2005, 12:16

Сообщение Ugrael » 30 ноя 2005, 16:30

заканчваться то заканчивается цикл. некст то я делаю dbf файлу.
а вот насчет commit - это я да, пролетел .... 8(

чуть позже опробую твой способ.

и , логически рассуждая, я так понимаю, что должно быть быстрее если загнать сначала dbf куда нибудь. например в память ?

Ivan_Pisarevsky
Заслуженный разработчик
Сообщения: 644
Зарегистрирован: 15 фев 2005, 11:34

Сообщение Ivan_Pisarevsky » 01 дек 2005, 08:25

должно быть быстрее если загнать сначала dbf куда нибудь. например в память ?
напимер в экстернал тэйбл :wink:

MMF
Сообщения: 17
Зарегистрирован: 17 дек 2004, 17:59

Сообщение MMF » 01 дек 2005, 13:56

Еще выкинь из цикла все FieldByName

Ugrael
Сообщения: 23
Зарегистрирован: 10 окт 2005, 12:16

Сообщение Ugrael » 16 дек 2005, 10:42

MMF писал(а):Еще выкинь из цикла все FieldByName
а что поставить ?

с помощью инсерт быстро, но это сначала приходится конвертить дбф.
лишнее звено....

Ответить