Форум: "Базы";
Текущий архив: 2002.07.22;
Скачать: [xml.tar.bz2];
ВнизСкоросная закачка в Interbase Найти похожие ветки
← →
Ptr (2002-06-25 09:01) [0]ПОМОГИТЕ СОВЕТОМ!!!
Закачка в InterBase 5934 записей продолжается 6 мин 12 сек !!!
Пробывал разные варианты:
- IBTable.Append;
- IBDataSet.Append;
- IBSQL.ExecQuery("insert into Base1 (Field1, ... Field10)
values (:Value1, ... :Value10)");
Разница в секундах.
А может быстре InterBase не может ???
(Сервер локальный и сеть не влияет.)
← →
Kaban (2002-06-25 09:02) [1]а откуда данные беруться?
← →
Ptr (2002-06-25 09:07) [2]Данные беруться из Excel?, но при отключении непосредственно операции записи т.е. // IBComponent.Воткнуть запись
Все работает менее 1 сек.
← →
Kaban (2002-06-25 09:09) [3]а код можно взглянуть
← →
Alexandr (2002-06-25 09:25) [4]быстрее должно быть через IBSQL, и транзакцию после каждого инсерта не дергай.
И индексы отключи и триггеры. Вот тогда быстродействие будет нормальным.
И главное ForceWrites не забудь выключить
← →
Ptr (2002-06-25 09:27) [5]procedure ImportAccount;
var StartT,EndT: TTime;
begin
IBDM.IBOperList.DisableControls;
wwDBGrid1.BeginUpdate;
StartT := Time;
try
while SRow <= ERow do // Определены выше
try
MainStatusBar.Panels[1].GaugeAttrs.Position := Trunc(SRow*100/ERow);
if not IBDM.AppendAccount(SRow,IBDM.IBOperList) then
raise Exception.Create(Ошибка записи. Строка: "+ IntToStr(SRow)+ " Sheet: "+ Sh.Name);
Inc(SRow);
MainForm.Refresh;
except
On E: Exception do
begin
MessageDlg(E.Message,mtError,[mbOK],0);
if ShowExcelErrorRow(sh.Name,SRow) then
Continue;
exit;
end;
end;
finally
IBDM.IBOperList.EnableControls;
wwDBGrid1.EndUpdate;
EndT := Time;
ShowMessage(TimeToStr(EndT-StartT));
end;
end;
//............................................................................
function TIBDM.AppendAccount(ExcelRw: integer; Base: TIBDataSet): boolean;
type
TImportField = record
x1, x2, x3: ShortString;
Date: TDateTime;
x4,x5,x6,x7: Currency;
end;
var
PR: TImportField;
begin
Result := true;
// check EXCELdata
with ExcelWorksheet do
begin
PR.x1:= Name;
if VarIsEmpty(Cells.Item[ExcelRw,1].value) then exit
else PR.Date := Cells.Item[ExcelRw,1].value;
if Cells.Item[ExcelRw,2].FormulaR1C1 = "" then PR.x2:= "-"
else PR.x2:= Cells.Item[ExcelRw,2].FormulaR1C1;
if Cells.Item[ExcelRw,3].FormulaR1C1 = "" then PR.x3:= "-"
else PR.x3:= Cells.Item[ExcelRw,3].FormulaR1C1;
if VarIsEmpty(Cells.Item[ExcelRw,5].Value) then PR.x4:= 0
else PR.x4:= RoundTo(Cells.Item[ExcelRw,5].value,-2);
if VarIsEmpty(Cells.Item[ExcelRw,6].Value) then PR.x5:= 0
else PR.x5:= RoundTo(Cells.Item[ExcelRw,6].value,-2);
if VarIsEmpty(Cells.Item[ExcelRw,7].Value) then PR.x6:= 0
else PR.x6:= RoundTo(Cells.Item[ExcelRw,7].value,-2);
if VarIsEmpty(Cells.Item[ExcelRw,8].Value) then PR.x7:= 0
else PR.x7:= RoundTo(Cells.Item[ExcelRw,8].value,-2);
end;
if not Base.Locate(Pole1; Pole2; Pole3; Pole4; Pole5; Pole6; Pole7; Pole8",VarArrayOf([PR.x1,PR.Date,PR.x2,PR.x3,PR.x4,PR.x5,PR.x6,PR.x7]),[]) then
with Base do
try
// try
IBSQL.ParamByName("x1").AsString := PR.x1;
IBSQL.ParamByName("x2").AsDateTime := PR.Date;
IBSQL.ParamByName("x3").AsString := PR.x2;
IBSQL.ParamByName("x4").AsString := PR.x3;
IBSQL.ParamByName("x5").AsDouble := RoundTo(ExcelWorksheet.Cells.Item[ExcelRw,4].Value,-2);
IBSQL.ParamByName("x6").AsDouble := PR.x4;
IBSQL.ParamByName("x7").AsDouble := PR.x5;
IBSQL.ParamByName("x8").AsDouble := PR.x6;
IBSQL.ParamByName("x9").AsDouble := PR.x7;
IBSQL.ParamByName("x10").AsDouble := RoundTo(ExcelWorksheet.Cells.Item[ExcelRw,16].Value,-2);
IBSQL.ParamByName("x11").AsDouble := RoundTo(ExcelWorksheet.Cells.Item[ExcelRw,17].Value,-2);
IBSQL.ParamByName("x12").AsDouble := RoundTo(ExcelWorksheet.Cells.Item[ExcelRw,18].Value,-2);
IBSQL.ParamByName("x13").AsDouble := RoundTo(ExcelWorksheet.Cells.Item[ExcelRw,19].Value,-2);
IBSQL.ExecQuery;
except on E: Exception do
begin
Base.Cancel;
MessageDlg(E.Message, mtError,[mbOk], 0);
Result := false;
end;
end;
end;
← →
Alexandr (2002-06-25 09:31) [6]у тебя что AutoCommit стаит? Выключи. Делай вручную commit когда все вставишь.
ParamByName долго. Лучше Params[...]
А что за Base.Locate? Надо бы без этого. Отсюда тоже тормоза большие.
← →
Ptr (2002-06-25 09:39) [7]1. Блокировка т.е. // Base.Locate уменьшает до 5 мин. 40 сек.
2. ParamByName долго, но это копейки
3. Где выключить AutoCommit???
← →
Alexandr (2002-06-25 09:44) [8]где-где? У IBSQL естественно.
Про блокировку не понял при чем тут Locate и блокировка?
И все-таки как насчет ForceWrites у базы и тескта запроса у IBSQL...
← →
Ptr (2002-06-25 09:56) [9]Я имел ввиду коментирование оператора locate существенно не помогает.
Текст запроса IBSQL.SQL:=
"insert into CLIENT_OPERATIONS
(Field1,..., Field 10)
values
(:Parm1,..., :Parm10)"
Где выключить AutoCommit???
а ForceWrites нашел в Helpe только для TIBDatabaseInfo ???
← →
Alexandr (2002-06-25 10:01) [10]Для Отключения ForceWrites возьми IBConcole и для базы данных отключи этот флаг.
А вообще странный ты какой-то там чуть-чуть тут чуть-чуть вот в сумме тормоза и получаются.
А код твой вообще в базу данные вставляет?
А то действительно у IBSQL нет свойства AutoCommit, но Commit - то кто-то должен транзакции делать...
← →
Ptr (2002-06-25 10:10) [11]C "там чуть-чуть тут чуть-чуть вот в сумме тормоза и получаются" согласен, но тут что-то координально надо менять...
База конечно заполняется т.к. у IBTransaction.DefaultAction стоит TACommit. Но
type TTransactionAction = (taRollback, taCommit, taRollbackRetaining, taCommitRetaining);
property DefaultAction: TTransactionAction;
Кроме того у IBSQL нет свойства CachedUpdates, чтобы включить Кэширование...
← →
sniknik (2002-06-25 10:16) [12]Ptr: ParamByName долго, но это копейки
Не скажи, это очень замедляет. Правда не знаю как в IB но BDE ускоряется раза в три.
Ускорил так както перекачку таблици 3100 зап. с 5сек до 1сек с мелочью.
теперь только так и делаю.
перед циклом определяю номера записей
MasT1[0]:= TDest.FieldByName("TYPE").Index; MasT2[0]:= 0;
MasT1[1]:= TDest.FieldByName("CODE").Index; MasT2[1]:= TSour.FieldByName("BARCODE").Index;
MasT1[2]:= TDest.FieldByName("GR1").Index; MasT2[2]:= TSour.FieldByName("GROOP1").Index;
MasT1[3]:= TDest.FieldByName("GR2").Index; MasT2[3]:= TSour.FieldByName("GROOP2").Index;
а в циклах обращение только по номеру
TDest.Fields[MasT1[0]].AsString:= " 4";
TDest.Fields[MasT1[1]].AsString:= st;
TDest.Fields[MasT1[2]].AsString:= TSour.Fields[MasT2[2]].AsString;
TDest.Fields[MasT1[3]].AsString:= TSour.Fields[MasT2[3]].AsString;
но это если только не получается SQL использовать или BatchMove.
← →
Alexandr (2002-06-25 10:19) [13]а зачем IBSQL свойство CachedUpdates?
Да и DefautAction тут вообще никаким боком...
Я же говорил про ForceWrites флаг в базе данных...
А индексы есть на этой таблице?
← →
Ptr (2002-06-25 10:24) [14]Мне кажется, что еще быстрее будет непосредственное обращение к полю (в твоем случае например TDestTYPE.value := "4" т.к. asString дополнительно требует затрат, а тип поля определен явно)
Но у меня другой случай. Хотя я уже
ПЕРЕПИСАЛ КОД НА IBAQL.PARM[].
← →
Alexandr (2002-06-25 10:27) [15]у тебя ОС какая? Win2000.
Так посмотри кто процессорное время жрет, Кто является источником тормозов.
IB, твоя программа, диск.
← →
Desdechado (2002-06-25 10:32) [16]имхо, главные тормоза от неявного использования транзакций. на каждое добавление в таком случае отдельная транзакция происходит. определи транзакцию явно перед закачкой, вставь все записи и закоммить.
← →
Alexandr (2002-06-25 10:33) [17]ах вот каков этот IBSQL... Я догадывался, но не знал как именно такое в нем происходит.
← →
Ptr (2002-06-25 10:35) [18]Интересно, но обращений к винту практически нет, ну а все процессорное время (99%) жрет собственно сама прогамма...
Индексы есть
← →
Alexandr (2002-06-25 10:40) [19]именно твоя программа, а не IBServer.exe?
Значит тормоза у тебя в программе
так как насчет явного StartTransaction - Commit
← →
Ptr (2002-06-25 11:05) [20]IBServer.exe практически в 0%
моя программа я тут потестировал и смотри, что получается
коментирую весь код процедуры за исключением Locate = время работы 3"17""
коментирую весь код процедуры за Parm[index]:= value
- время работы 1"37""
Кстати и только загрузка параментров из Excel (т.е.):
if VarIsEmpty(Cells.Item[ExcelRw,1].value) then exit
else PR.Date := Cells.Item[ExcelRw,1].value;
if Cells.Item[ExcelRw,2].FormulaR1C1 = "" then PR.x2:= "-"
else PR.x2:= Cells.Item[ExcelRw,2].FormulaR1C1;
if Cells.Item[ExcelRw,3].FormulaR1C1 = "" then PR.x3:= "-"
else PR.x3:= Cells.Item[ExcelRw,3].FormulaR1C1;
if VarIsEmpty(Cells.Item[ExcelRw,5].Value) then PR.x4:= 0
else PR.x4:= RoundTo(Cells.Item[ExcelRw,5].value,-2);
if VarIsEmpty(Cells.Item[ExcelRw,6].Value) then PR.x5:= 0
else PR.x5:= RoundTo(Cells.Item[ExcelRw,6].value,-2);
if VarIsEmpty(Cells.Item[ExcelRw,7].Value) then PR.x6:= 0
else PR.x6:= RoundTo(Cells.Item[ExcelRw,7].value,-2);
if VarIsEmpty(Cells.Item[ExcelRw,8].Value) then PR.x7:= 0
else PR.x7:= RoundTo(Cells.Item[ExcelRw,8].value,-2);
тоже долго работает - 4" 12""
Процессор p4 2 ГГц и винт 7500 об.
А насчет "явного StartTransaction - Commit" конечно ты прав нет смысла записывать после каждой записи. Теперь думаю, как это убрать...
← →
Alexandr (2002-06-25 11:11) [21]ну вот видишь
← →
Ptr (2002-06-25 11:18) [22]СПАСИБО ЗА УЧАСТИЕ!!! Бду дальше ломать голову...
← →
DarkGreen (2002-06-25 14:11) [23]Попробуй вместо IBX использовать FreeIBPlus, IMHO они быстрее. У меня подобная задачка была, нужно было пакетно из текстового файла закачать ~ 20000 записей, на IBX я так ни чего и не добился, работала в лучшем случае 5 минут (в начале было 20 минут), а на FIBPlus 1 минута, хотя конечно я довольно долго добивался этого результата.
Но если коротко. Как говорили выше, никогда не используй ParamByName и FieldByName они поля ищут простым перебором (про Locate молчу, там вообще мраки (взгляни в исходный код)). Для добавления записей используй хранимые процедуры. Комить через каждые 200 - 300 вставок.
← →
Andrew_Kandaurov (2002-06-25 19:01) [24]Все тормоза от Excel. Експортни екселевский файл в txt или csv. А из него уже и закачивай обычными паскалевскими READ-ами. Потому что все эти CELLS,ITEMS и т.д. работают крайне медленно.
← →
Ptr (2002-07-02 10:46) [25]Спасибо друзья.
Проблема решилась когда я перешед на клиента (т.е. TSQLDataSet) и закачку осуществляю один раз в конце.
Так 100000 записей грузятся около 8 сек. Правда закачка на сервер идет порядка 1 мин, но это уже мелочи...
Еще раз спасибо.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2002.07.22;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.006 c