![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как правильно закачивать в базу большие объемы данных?
Defunct © (2005-08-04 05:14:00)обычный insert into (..) жутко медленно работает ~1k записей в сек.. Транзакцию закрываю через каждые 5k записей. В качестве исходных данных - текстовые файлы, объемом всреднем по ~500mb, чувствую если заливаться данные в базу будут как сейчас, то уйдет несколько недель.. Подскажите пож. способы ускорения работы insert'a
БД - IB6.5/FB1.5
ЮЮ (2005-08-04 08:52:00) [41]1) insert ещё и индексы модифицирует, целостность проверяет
2) select * все=таки одна инструкция серверу :)
выполни
select * ... where id = :id
в таком же цикле и оцени
sniknik (2005-08-04 08:51:00) [42]> Просто как-то не верится, что select * выполняется за считанные секунды, а insert на четыре порядка дольше.
insern всегда дольше, вопрос лиш в том на оправданое время "дольше" или нет.
сама запись на винт дольше чем чтение, перестройка индексов, подготовка страниц для записи... все время занимает.
в принципе неправильно построенные/лишние индексы могут очень запись в базу затормозить, например если сделать кластерный индекс для поля в которое значения поступают хаотично и в основном в порядке от большго к меньшему (а индекс их перестраивает наоборот, и то что он кластерный значит и записи таблици в том же порядке выстраиваются...).
Defunct (2005-08-04 08:38:00) [43]ЮЮ © (04.08.05 07:51) [3]
Спасибо, сделаю как Вы говорите!
Но настораживает вот что, CPU usage заливающей программы - 6-8%, в то время как выделенный сервер, куда заливаются данные загружен на 60-80% (такая загрузка появляется именно при исполнении приведенного в [2] кода). Может быть есть кардинально другой способ занесения данных в базу, не так сильно загружающий сервер?
Просто как-то не верится, что select * выполняется за считанные секунды, а insert на четыре порядка дольше.
ЮЮ (2005-08-04 07:51:00) [44]1)
IQuery.Params[0].AsInteger := id;
...
IQuery.Params[5].AsString := ParsedRecord.Url;
2)
для каждой записи выполняется много телодвижений в StartTransaction и Commit
Defunct (2005-08-04 07:01:00) [45]> мог бы и показать чуток того, что скрыто за ..
разумеется:
StartTransaction;
if not IQuery.Prepared then
begin
IQuery.SQL.Add('insert into http_proxy(ID, FKEY, IP, MDATE, ANSWER, ASIZE, URL) ');
IQuery.SQL.Add('values(:ID, :FKEY, :IP, :MDATE, :ANSWER, :ASIZE, :URL);');
IQuery.Prepare;
end;
IQuery.ParamByName('ID').AsInteger := id;
IQuery.ParamByName('FKEY').AsInteger := ParsedRecord.fKey;
IQuery.ParamByName('MDATE').AsFloat := ParsedRecord.Date;
IQuery.ParamByName('IP').AsInteger := ParsedRecord.ip;
IQuery.ParamByName('ANSWER').AsInteger := ParsedRecord.Ack;
IQuery.ParamByName('ASIZE').AsInteger := ParsedRecord.Size;
IQuery.ParamByName('URL').AsString := ParsedRecord.Url;
IQuery.ExecSQL;
Commit( False );
except
...
procedure TDataModule.StartTransaction;
begin
if Connected and (not DB.InTransaction) then
DB.StartTransaction;
end;
procedure TDataModule.Commit( Forced: boolean );
begin
if Connected then
begin
CS.Acquire;
try
if DB.InTransaction then
begin
inc(ChangesCount);
if Forced or (ChangesCount > 5000) then
begin
ChangesCount := 0;
DB.Commit;
IQuery.UnPrepare;
IQuery.SQL.Clear;
end
end
finally
CS.Release
end
end
end;
ЮЮ (2005-08-04 06:21:00) [46]>обычный insert into (..)
мог бы и показать чуток того, что скрыто за ..
запрос параметрический, перед первым использованием Prepare