-
For i:= 0 to 700000 do
begin
Application.ProcessMessages;
PBZagruzka.Position:= i;
IntTipEda:= Random(2);
IntXEda:= Random(IntXRazm);
IntYEda:= Random(IntYRazm);
DataM.ADOQEda.SQL.Clear;
DataM.ADOQEda.SQL.Add('INSERT INTO Координаты_еды ([Тип_еды], [Х], [У]) VALUES (' +
IntToStr(IntTipEda) + ',' + IntToStr(IntXEda) + ',' + IntToStr(IntYEda) + ')');
DataM.ADOQEda.ExecSQL;
end;
Всем привет! Вот я сделал цикл для записи в базу данных строк со случайно сгенерированными числами. Строк около 700000. Запись происходит долго, понятно конечно что Application.ProcessMessages; тормозит цикл и лучше сделать отдельный поток. Искал как сделать можно запросом запись без цикла и ненашел ничего подобного. Подскажите как можно ускорить это дело или это все что можно выжать из этого? Может какие то настройки еще не сделал запросы посылаю через ADOQuery база данных создана в Access.
-
В INSERT INTO можно передать сразу много строк для записи, а не по одной.
-
можно но на сколько я понял добавлять можно только строки из другой таблицы пачкой сразу. Смысл цикла создать координаты так чтобы они не совпадали были уникальные типа.
-
> понятно конечно что Application.ProcessMessages; тормозит цикл и где это таким "понятиям" учат? вызов процедуры делается очень быстро... гораздо быстрее чем например "обслуживание" структур для обработки данных в ADOQuery, которые ты все одно не используешь... и уж точно чем пере создание в цикле, при отсутствии параметров...
-
> только строки из другой таблицы из файла.
-
For i:= 0 to 700000 do begin Application.ProcessMessages; { PBZagruzka.Position:= i; IntTipEda:= Random(2); IntXEda:= Random(IntXRazm); IntYEda:= Random(IntYRazm); DataM.ADOQEda.SQL.Clear; DataM.ADOQEda.SQL.Add('INSERT INTO Координаты_еды ([Тип_еды], [Х], [У]) VALUES (' + IntToStr(IntTipEda) + ',' + IntToStr(IntXEda) + ',' + IntToStr(IntYEda) + ')'); DataM.ADOQEda.ExecSQL; } end; Сколько времени занимает, и сколько если убрать {}
-
упс там фигурные скобки недолжно быть это я забыл убрать когда скопировал в форум. минут 40 идет создание базы. А то что хотел сказать sniknik я не понял...
-
Где не должно быть? Ты поставь где я указал и сообщи результат. И где идет создание базы? Ты вообще о чем говоришь то?
-
> А то что хотел сказать sniknik я не понял... чего непонятного? по пунктам 1 - ProcessMessages не занимает времени, нечего на него валить. 2 - ускорить можно изучив НОРМАЛЬНУЮ работу с базой, используя НОРМАЛЬНЫЕ компоненты (т.е. не ADOTable, не ADOQuery, не ADOStoredProc). 3 еще больше можно ускорить изучив особенности работы конкретного движка (Jet), в частности загрузку из файла (Text ISAM)
а пока не хочешь изучать, а "валишь" вину на других... довольствуйся тем что есть. и кстати, отдельный поток не поможет. потоки вообще скорости не добавляют, наоборот уменьшают, просто делают работу параллельно основному (ну и какой смысл ее делать так если пользователь ждет окончания действий... ну вот нажал заполнить, и он что на те 3-5 сек которые ему параллельно выделили, на другую задачу переключится? типа на стирание данных? или их редактирование?).
-
> Ты поставь где я указал и сообщи результат.
Результаты: ProcessMessages примерно 2 секунды все сделал перебрал в цикле 700000 раз переменную тупо, если поставить фигурные скобки как вы показали. А если убрать скобки то работает 3 часа почти пока создаст базу данных.
> И где идет создание базы?
База данных создается в Microsoft Office Access 2007.
> ProcessMessages не занимает времени, нечего на него валить.
Я же предпологал тока, я знаю что он замедляет работу в циклах делает что то вроде прерывания цикла для того чтобы невозникало зависание программы полного и была реакция на другие события в программе. Теперь знаю что он довольно быстро работает всего 2 секунды тратит от работы моей записи в базу. Я ошибся извиняйте. И на щет потока тоже ступил, еще мало узнал про них.
> ускорить можно изучив НОРМАЛЬНУЮ работу с базой, используя > НОРМАЛЬНЫЕ компоненты
Опять не те компоненты. Вначале ADOTable ненравился в прошлом посте форума делай говорят через SQL запросы... сделал. Теперь опять не те компоненты теперь ADOQuery неподходит. Как тогда запрос то посылать в базу в книгах (Библия Delphe, Дельфи для профессионалов, Фаронов Delphi 7 Программирование баз данных, Delphi 7 на примерах) нет другого способа я невидел :(((
> изучив особенности работы конкретного движка (Jet), в частности > загрузку из файла (Text ISAM)
Теперь надо в движок лезть новичку и пытатся что то там понять немыслимо сделанное профи. Я так и останусь зеленым и неопытным если буду понять то что еще наверное рано, а может не рано...
-
> Neiron (30.10.2011 16:16:09) [9]
Ну так кто тормозит? И еще раз, а где создание базы?
-
> И еще раз, а где создание базы?
Вы хотите более подробный код? Я немогу понять вопрос ваш???
-
Вот полный код при нажатии на кнопку, сама база данных создана вручную в Access и имеет следующие поля: Key - ключевое поле, индексированное, счетчик со случайными числами; Тип_еды - числовое поле, не индексированное, числовое; X - координата положения еды по х для отображеня в PaintBox, поле не индексированное, числовое; У - координата положения еды по y для отображеня в PaintBox, поле не индексированное, числовое.
procedure TGeneralForm.MenuStandNachalaClick(Sender: TObject);
var
i, IntTipEda, IntMaxEda, IntXEda, IntYEda: integer;
begin
SBar.Panels[0].Text:= 'Время мира - 00:00:00';
SBar.Panels[1].Text:= 'Темп. - 0';
SBar.Panels[2].Text:= 'Влаж. - 0';
SBar.Panels[3].Text:= 'Радиация - 0';
SBar.Panels[4].Text:= 'Клеток - 0';
SBar.Panels[5].Text:= 'Пищи - 0';
SBar.Panels[6].Text:= 'Вирусов - 0';
ListBDeistviaKletki.Items.Clear;
CBoxViborKletki.Clear;
CBoxViborKletki.Text:= '0';
DataM.ADOQDNK.ConnectionString:= 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=' +
ExtractFilePath(Application.ExeName) +
'\База данных Эволюции.mdb' + ';Persist Security Info=False';
DataM.ADOQDNK.Active:= true;
DataM.ADOQDNK.SQL.Clear;
DataM.ADOQDNK.SQL.Add('DELETE FROM ДНК_клеток');
DataM.ADOQDNK.ExecSQL;
DataM.ADOQDNK.SQL.Clear;
DataM.ADOQDNK.SQL.Add('INSERT INTO ДНК_клеток ([№_клетки],[Цвет],[Размер],[Масса],[Жизнь],' +
'[Ошибка_копир _ДНК],[Скорость_деления],[Бак_с_Е],[Е_для_деления],' +
'[Е_для_сенсора],[Е_для_движения],[№_клеток_в_орган],[№_жгутиков],' +
'[Дальн_сенсора],[Скор_движения],[Коор_клетки_Х],[Коор_клетки_У],' +
'[Коор_пищи_Х],[Коор_пищи_У],[Действий_клетки]) ' +
'VALUES(1, 100, 6, 6, 60, 0, 2, 25, 20, 10, 1, 1, 1, 40, 1, 0, 0, 0, 0, 0)');
DataM.ADOQDNK.ExecSQL;
DataM.ADOQEda.ConnectionString:= 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=' +
ExtractFilePath(Application.ExeName) +
'\База данных Эволюции.mdb' + ';Persist Security Info=False';
DataM.ADOQEda.Active:= true;
DataM.ADOQEda.SQL.Clear;
DataM.ADOQEda.SQL.Add('DELETE FROM Координаты_еды');
DataM.ADOQEda.ExecSQL;
IntXRazm:= PBWord.Width;
IntYRazm:= PBWord.Height;
IntMaxEda:= Trunc((IntXRazm*IntYRazm)/40);
PBZagruzka.Position:= 0;
PBZagruzka.Max:= IntMaxEda;
PBZagruzka.Visible:= true;
LabZagruzka.Visible:= true;
For i:= 0 to IntMaxEda do
begin
Application.ProcessMessages;
Edit1.Text:= IntToStr(IntMaxEda) + '/' + IntToStr(i);
PBZagruzka.Position:= i;
IntTipEda:= Random(2);
IntXEda:= Random(IntXRazm);
IntYEda:= Random(IntYRazm);
DataM.ADOQEda.SQL.Clear;
DataM.ADOQEda.SQL.Add('INSERT INTO Координаты_еды ([Тип_еды], [Х], [У]) VALUES (' +
IntToStr(IntTipEda) + ',' + IntToStr(IntXEda) + ',' + IntToStr(IntYEda) + ')');
DataM.ADOQEda.ExecSQL;
end;
PBZagruzka.Visible:= false;
LabZagruzka.Visible:= false;
TimerWord.Enabled:= true;
end;
-
> Вначале ADOTable ненравился что значит в начале? я тут чуть ли не с начала века за "родные" компоненты борюсь, вместо замен для привыкших к BDE, переходящих с него... ты переходишь?
> нет другого способа я невидел :((( ADODataSet для возвращающих данные запросов/пакетов/процедур, и ADOCommand для командных(не возвращающих) запросов/...
> Теперь надо в движок лезть новичку ну во первых вопрос задан не в "новичках", а во вторых таки да, хочется скорости нужно изучать досконально то, что используешь. в любом деле (вон слышал что даже шоферы на ручной коробке дают лучшие результаты чем на "автомате"... ну, это если знают тонкости. а программирование оно посложнее будет)
-
> Вот полный код при нажатии на кнопку вот кстати еще один "тормоз" - > PBZagruzka.Position:= i; отрисовка 700 тыс раз... а сколько "кубиков" ты видишь в компоненте?
+ отсутствие компонента коннекта.
-
> то работает 3 часа вот, приведенный (более менее) в порядок код. procedure TForm1.Button5Click(Sender: TObject);
var
i: integer;
pIntTipEda, pIntXEda, pIntYEda: TParameter;
begin
ADOCon.ConnectionString:=
'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=' +
ExtractFilePath(Application.ExeName) +
'\База данных Эволюции.mdb' + ';Persist Security Info=False';
ADOQEda.CommandText:= 'DELETE FROM Координаты_еды';
ADOQEda.Execute;
ADOQEda.CommandText:=
'INSERT INTO Координаты_еды ([Тип_еды],[X],[Y]) VALUES (:IntTipEda, :IntXEda, :IntYEda)';
pIntTipEda:= ADOQEda.Parameters.ParamByName('IntTipEda');
pIntXEda := ADOQEda.Parameters.ParamByName('IntXEda');
pIntYEda := ADOQEda.Parameters.ParamByName('IntYEda');
for i:= 1 to 70000 do begin
pIntTipEda.Value:= Random(2);
pIntXEda.Value := Random(200);
pIntYEda.Value := Random(200);
ADOQEda.Execute;
if (i mod 1000) = 0 then Label1.Caption:= IntToStr(i);
Application.ProcessMessages;
end;
end; работает примерно 4 мин (без 15 сек), т.е. в 10 больше (700 тыс вместо 70) будет 40 мин. и это даже если не "лезть в движок"... просто нормально писать.
-
> что значит в начале? я тут чуть ли не с начала века за "родные" > компоненты борюсь, вместо замен для привыкших к BDE, переходящих > с него... ты переходишь?
Я просто хотел поучится с базами данных работать. На одной из веток форму тут я задавал вопрос как с ADOTable в Access сделать еще одно поле, итогом беседы было что SQL типа проще использовать и он универсальный в разных осях по крайней мере в тех которые меня интересуют (Виндовс ХР и Виндовс 7). > ADODataSet для возвращающих данные запросов/пакетов/процедур, > и ADOCommand для командных(не возвращающих) запросов/..
Это че мне еще надо 2 компонента использовать для работы с базой данных своей? > вопрос задан не в "новичках"
Извиняйте в следующий раз не буду тут писать. > > Вот полный код при нажатии на кнопкувот кстати еще один > "тормоз" -> PBZagruzka.Position:= i;отрисовка 700 тыс раз. > .. а сколько "кубиков" ты видишь в компоненте?
А как еще то показать юзеру что идет загрузка программы? Везде используют прогресс бары а тут мой тормозит все прямо. Может уменьшить надо количество раз в цикле на обращение к PBZagruzka.Position:= i; с помощью условия If ... then? > + отсутствие компонента коннекта.
Зачем компонент конекта если в ADOQuery есть тоже самое подключение. Я думаю он лишний, и без него все работает и подключается.
-
> просто нормально писать. в смысле, тут вообще то логика отсутствует напрочь... нормально, но "дубово". не делал бы так естественно, а сделал бы что то типа начального наполнения например на 100 записей, а после инсерт "самой в себя" но с подставленными в запрос вычислениями случайных значений... (ведь тут не нужно какихто конкретных) время сократится на порядок... т.е. предположительно пару минут на все 700 тыс. и опять в движок лезть не надо, просто думать... вернее нет, сначала нужно знать sql, а после думать как его применять...
-
> Везде используют прогресс бары а тут мой тормозит все прямо. везде используют,и обновляют компонент только когда нужно рисовать (новый кубик открылся), а ты примерно 7 тыс раз один и тот же перерисовываешь... думаешь это добавляет программе скорости?
-
> Neiron © (30.10.11 12:21) [2] > можно но на сколько я понял добавлять можно только строки из другой таблицы пачкой сразу.Ну так да. Только создай эту таблицу в текстовом файле, а потом insert into table (...) select * from [tmp.txt] in "c:\tmp-location" "Text;HDR=Yes" Вроде в msdn всё написано.. > Смысл цикла создать координаты так чтобы они не совпадали были уникальные типа.Что-то у тебя не видно проверки на уникальность. И вообше.. Координаты_еды, ms access - это всё зачем вообще? Что за программа?
-
> Это че мне еще надо 2 не еще 2, а ТОЛЬКО эти два, + коннект (обязательно, даже если не понимаешь зачем). один конект, и кучу к нему подключений, а не так как у тебя у каждого свой. тоже если уж о скорости говорить, не добавляет.
но главнее всего логика, алгоритм... (перечитай 17, вникни. 40мин vs 2-3мин, за счет изменения алгоритма. ни одним компонентом такого не добьешся)
-
> Neiron © (30.10.11 18:19) [16
Чë скулишь? Зачем тебе это программирование? Есть много других профессий.
-
> Я думаю он лишний, и без него все работает и подключается. значит ты дебил. ничего не знаешь, спросил, и не следуешь...
удачи.
> Зачем тебе это программирование? Есть много других профессий. +1 золотарей говорят не хватает... все в менеджеры ушли.
-
> Вроде в msdn всё написано..
а где его взять? Типа справка на английском чтоли в дельфи? Или чето другое имеете в виду? Я по книгам читаю и изучаю по вечерам, но там вечно в одной одного нет в другом другого в инете тоже нет справки по всем функциям хотя бы одной полной. Больше ищу ответы чем пишу код, прямо детектив какой то расследую.
> Что-то у тебя не видно проверки на уникальность.
Это я еще нереализовал, хотел посмотреть скока база сама то будет создаватся
Хочу попробовать сделать приспосаблиеваемость клетки к окружающей среде посредством естественного отбора, используя ошибку в ДНК клетки как двигатель эволюции. Просто интерсный эксперимент такой :). В программе есть клетка она ест еду и есть окружающая среда как сама клетка так и окружающая среда могут влиять друг на друга (клетка есть получает энергию которую может потратить на разные действия найти еду, двигатся, поделится сделав копию себя. При трате энергии она изменяет температуру окружающей среды, если температура не в пределах жизни клетки тогда повышается процент ошибки копирования ДНК при делении клетки и будут в ДНК изменятся параметры она мутирует типа приспасабливается или деградирует и вымрет). Есть и другие источники мутации как вирусы клетка наткнется если на него то тоже мутирует. У клетки еще будет типа в ДНК записан алгоритм жизнедеятельности типа живет по определенной программе, если бак энергии полный то делится потом сканирует местность на еду, потом движется и ест потом снова теже операции, на этот алгоритм жизни ее тоже будет влиять мутация. Вот почему я делаю базу с координатами еды чтобы сохранить их и загрузить и продолжить наблюдение за миром этим. И интересно и базы данных изучаю еще, не в текстовом же файле хранить все эти координаты. Таблицами как то удобнее все.
Спасибо sniknik, оч полезный урок я много узнал интересного. Подскажите книжку плиз еще по SQL я незнаю какую выбрать???
-
> Neiron © (30.10.11 18:19) [16]
А ты что хочешь отделаться одним, или ленишься.
-
> А ты что хочешь отделаться одним, или ленишься.
я разберусь со всеми компонентами я стараюсь учится, извините за тупые вопросы.
> > Я думаю он лишний, и без него все работает и подключается. > значит ты дебил. ничего не знаешь, спросил, и не следуешь. > ..удачи.> Зачем тебе это программирование? Есть много других > профессий.+1золотарей говорят не хватает... все в менеджеры > ушли.
Мне нравится вот и занимаюсь, зачем грубить то!!! Спокойнее надо к людям относится. Вы тоже в свое время ничего не знали так что не надо показывать что если вы щас это знаете а я нет пока что то я хуже вас. Всему свое время. :)
-
> Вы тоже в свое время ничего не знали и что? тебе ;е не из-за того "грубят", что не знаешь, а из-за того, что после объяснений (о чем ты кстати просил) ты их игнорируешь, "думаешь" видите ли. пока "нулевый" не думай, вникай в то, что дают.
-
все понял. Уже читаю и разбираю твой код и компоненты тоже. Всем спасибо за терпение.
-
> На одной из веток форму тут я задавал вопрос как с ADOTable > в Access сделать еще одно поле, итогом беседы было что SQL > типа проще использовать и он универсальный
Ну я это говорил. Ко мне претензии есть?
-
110 секунд Query.CommandText:='INSERT INTO Координаты_еды ([Тип_еды], [Х], [У]) VALUES (:Tip, :X,:Y);';
Query.Prepared:=true;
for i:= 0 to 70000 do
begin
Query.Parameters[0].Value:=Random(2);
Query.Parameters[1].Value:= Random(640);
Query.Parameters[2].Value:= Random(480);
Query.Execute;
if (i mod 100) =0 then
begin
Caption:=(inttostr(i));
Application.ProcessMessages;
end;
end;
-
> Slym © (31.10.11 07:26) [29] > for i:= 0 to 70000 do
У автора на порядок больше )
-
Ну и что, подумаешь будет 1100 секунд, кроме того можно if (i mod 1000) =0 then
-
> У автора на порядок больше ) и по времени, того порядка = этому результату (3 часа). а нормальный компонент/написание тоже самое "в лоб" делает за 40 мин. вот что кре... ADOCommand животворящий делает! ;)
-
10 сек procedure TForm1.Button1Click(Sender: TObject);
var
i: integer;
DB:TADOConnection;
Query:TADOCommand;
cvs:TFileStream;
s:string;
tick:DWORD;
begin
tick:=GetTickCount;
DB:=TADOConnection.Create(nil);
try
DB.ConnectionString:= 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=' +
ExtractFilePath(Application.ExeName) +'\База данных Эволюции.mdb';
DB.Connected:=true;
Query:=TADOCommand.Create(nil);
try
Query.Connection:=DB;
Query.CommandText:='DELETE FROM ДНК_клеток';
Query.Execute;
Query.CommandText:='INSERT INTO ДНК_клеток ([№_клетки],[Цвет],[Размер],[Масса],[Жизнь],' +
'[Ошибка_копир_ДНК],[Скорость_деления],[Бак_с_Е],[Е_для_деления],' +
'[Е_для_сенсора],[Е_для_движения],[№_клеток_в_орган],[№_жгутиков],' +
'[Дальн_сенсора],[Скор_движения],[Коор_клетки_Х],[Коор_клетки_У],' +
'[Коор_пищи_Х],[Коор_пищи_У],[Действий_клетки]) ' +
'VALUES(1, 100, 6, 6, 60, 0, 2, 25, 20, 10, 1, 1, 1, 40, 1, 0, 0, 0, 0, 0);';
Query.Execute;
Query.CommandText:='DELETE FROM Координаты_еды;';
Query.Execute;
cvs:=TFileStream.Create('Data.txt',fmCreate);
try
for i:= 0 to 700000 do
begin
s:=Format('%d,%d,%d'#13#10,[Random(2),Random(640),Random(480)]);
cvs.WriteBuffer(PChar(s)^,Length(s));
end;
finally
cvs.Free;
end;
Query.CommandText:='DELETE FROM Координаты_еды;';
Query.Execute;
Query.ParamCheck:=false;
Query.CommandText:=
'INSERT INTO Координаты_еды SELECT txt.F1 as Тип_еды, txt.F2 as Х, txt.F3 as У FROM [Text;Database='+ExtractFilePath(Application.ExeName)+';HDR=No;FMT=Delimited].Data.txt AS txt;';
Query.Execute;
finally
Query.Free
end;
finally
DB.Free;
end;
tick:=GetTickCount-tick;
Caption:=IntToStr(tick);
end;
-
> sniknik (31.10.2011 09:26:32) [32]
А вывод какой, переписать все нафиг?
-
> Slym © (31.10.11 09:34) [33]
Это довод в пользу ADOCommand? ))
-
> А вывод какой, переписать все нафиг? пофиг.
> Это довод в пользу ADOCommand? )) в пользу особенностей движка (про фай с самого начала говорили будет быстрее всего), но вот на другом движке "ISAM-ов" может и не быть, но зато будут "линкед сервер"/OPENQUERY/т.д. какие нибудь.
-
> Это довод в пользу ADOCommand? )) тут же вместо 700000 вызовов делается 1 т.что собственно "тормоза" ADOQuery по сравнению с ADOCommand совершенно не важны.
-
Обычно работаю с BDE. Проверил сейчас по скорости он обходит существенно приведенные тут примеры. ADO нравится тем, что не требует доп.драйверов и настроек. Все в одном компонение - ADOConnection. Но если нужна именно скорость, что Вы обычно используете? Я смотрю, BDE сейчас никто не использует. Не хочется быть мамонтом.
-
> Neiron (30.10.2011 11:11:00) [0]
Замени на TAdoCommand и используй параметры
-
> Sergert (16.02.2012 15:54:38) [38]
АДО Только TAdoCommand + параметры
-
>Проверил сейчас по скорости он обходит существенно приведенные тут примеры.
а) На каких объемах и типах БД ? и б) А не задумывались почему ?
-
> Но если нужна именно скорость, что Вы обычно используете?
Уж точно не BDE, тот по скорости как раз проигрывает.
-
sniknik © (30.10.11 15:43) [8] > 2 - ускорить можно изучив НОРМАЛЬНУЮ работу с базой, используя > НОРМАЛЬНЫЕ компоненты (т.е. не ADOTable, не ADOQuery, не > ADOStoredProc).
А какие нормальные для запросов select?
-
а что большой выбор у ADO остался, после исключения тех, которые не нужно использовать?
-
> Как ускорить запись строк в Access запросом SQL [D7] Попробуй сделать вставку блоками (по 100 записей допустим). Формируешь запрос типа такого: INSERT INTO...
SELECT ....
UNION
SELECT..
UNION
SELECT И так 100 Select...
|