Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 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
8-70835
Olgerd
2002-03-15 20:08
2002.07.22
Текст на прозрачной фоне.


14-70908
lipskiy
2002-06-24 02:51
2002.07.22
Микропрограммки


1-70743
WorkMan
2002-07-05 07:34
2002.07.22
Статическая линковка библиотек.


14-70921
mifi
2002-06-25 00:42
2002.07.22
Скрипт


14-70866
AlexGreg
2002-06-24 12:18
2002.07.22
Дельфи под Oracle - обмен опытом





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский