-
>jack128_ (07.10.08 10:12) [19 >быстрее вставка происходить будет.
и фиг с ней, с целостностью ?
-
> Игорь Шевченко © (06.10.08 22:19) [13] > можно дураку объяснить - какой смысл в commit-е порциями > (ну скажем, по 500-1000 штук) ?
Смысл - не накапливать версии записей, ускорение. Почитать, как обычно, можно на ibase.ru > MsGuns © (07.10.08 00:50) [14] > И мне заодно тоже
В чем сомнения? > DelphiN!
Рекомендуется к прочтению http://www.ibase.ru/devinfo/ibx.htm
-
> и фиг с ней, с целостностью ?
а ты уверен, что вставка 500 записей нарушит целостность?
-
Johnmen © (07.10.08 10:27) [21]
> Смысл - не накапливать версии записей, ускорение. Почитать, > как обычно, можно на ibase.ru
Тогда чем плохо коммитить по одной ? Вопрос был о том, зачем именно пакет организовывать
-
Проблему решил обновлением компонентов IBX. Стояла старая, глючная версия .. Всем большое спасибо за помощь!
-
>jack128_ (07.10.08 10:50) [22] >а ты уверен, что вставка 500 записей нарушит целостность?
А ты уверен, что НЕ нарушит ?
А вообще корень проблемы раскрыт в [23]
-
> Игорь Шевченко © (07.10.08 10:53) [23] > Johnmen © (07.10.08 10:27) [21] > > Тогда чем плохо коммитить по одной ? Вопрос был о том, зачем > именно пакет организовывать
Потому что коммит после каждой записи также заметно замедляет работу. Оптимальный по производительности способ вставки больших массивов в IB - именно пакетами (количество записей в пакете зависит от многих параметров)
-
DrPass © (07.10.08 16:41) [26]
> Потому что коммит после каждой записи также заметно замедляет > работу. Оптимальный по производительности способ вставки > больших массивов в IB - именно пакетами (количество записей > в пакете зависит от многих параметров)
ну понятно - black voodoo. Желающие подкручивать гайки без хлеба не останутся. Но все-таки - насколько мне известно, IB не запускает сборку мусора после каждого commit, версии все равно зависят от количества одновременно стартовавших транзакций - какая физика механизма, что при транзакции "пакетом" быстродействие выше ? Если не затруднит, то ссылочку с ibase.ru
-
> IB не запускает сборку мусора после каждого commit,
Причем здесь вообще сборка мусора, если речь идет о вставке (а не удалении, обновлении и выборке) записей? Игорь, скажите, что эффективнее будет работать - пятьсот раз переписать страницу данных и один раз - страницу состояний транзакций в конце всего этого, или пятьсот раз переписать страницу данных и пятьсот раз страницу состояний транзацкий после каждой вставки? Имейте в виду, сервер IB обычно работает в режиме прямой записи на диск, без кеширования! Никакой черной магии, элементарная логика, подтвержденная опытом работы с сервером. Я понимаю, вы любитель поумничать. Но зачем умничать в тех областях, в которых вы слабо разбираетесь-то?
-
> количество записей в пакете зависит от многих параметров
Ерунда, это зависит только от дурости программиста. При работе с многострочным документом используется статус документа, коммитится же КАЖДАЯ введенная (исправленная) запись, при всевозможных "заливках" ничего лучше раскритикованного джонменом способа с временной таблицей нет во всех остальных случаях вполне достаточно "чистого" сиквеля
Все остальное - от лукавого
-
> сервер IB обычно работает в режиме прямой записи на диск, > без кеширования!
да ну по умолчанию как раз наоборот а вот если принудительно выставить ForceWrite, тогда да, это это для параноиков и на особо ответственных базах но массовая загрузка данных всегда отличалась от обычной работы, причем независимо от субд
-
> MsGuns © (07.10.08 17:32) [29]
холиваров не надо, каждый свое мнение может иметь, основанное на опыте
-
>DrPass © (07.10.08 17:28) [28] >Никакой черной магии, элементарная логика, подтвержденная опытом работы с сервером. Я >понимаю, вы любитель поумничать. Но зачем умничать в тех областях, в которых вы слабо >разбираетесь-то?
Давай без зеленых человечеков и словокатанием в духе "бывают случаи" Приведи практический пример, в котором приведенных в [29] вариантов не хватает для решения задачи. Только не надо мне рассказывать, что сервер на временную таблицу с последующим ЕДИНСТВЕННЫМ insert to ОСНОВНАЯ ТАБЛИЦА from select будет заморачиваться круче, чем "держать" версии стотыщмильонов записей, агрументируя аргументов, что он де работает без кеширования (причем тут это вообще непонятно)
А то мы так до третьих петухов будем "умничать"
-
DrPass © (07.10.08 17:28) [28]
> Никакой черной магии, элементарная логика, подтвержденная > опытом работы с сервером. Я понимаю, вы любитель поумничать. > Но зачем умничать в тех областях, в которых вы слабо разбираетесь- > то?
То есть, ссылочки на ibase.ru не будет, я верно понимаю ?
-
2 MsGuns © Временные таблицы - это стиль MSSQL, а не IB. Насчет оптималности подтверждения после каждых 5тыс. мог бы поспорить, так как конркетно для IB все равно, коммитить после каждых 5000 или после каждых 50 тыс. Почему, например, не после каждых 500? Насчет обработки ошибок согласен, я не показал этого в коде. Сознательно посчитал это излишним. Как, впрочем, и коммит после каждых 5000. Так как правильная обработка ошибок от задачи зависит. Например, человека может быть устроит вообще наглухо подавить все ошибки, нарушения уникального ключа (unique key violation) и при этом одновременно ни в коем случае не подавлять ошибки, связанные с обрезанием строки (в данном случае у него имя файла) по длине (string truncation). А так как у него (как он сам сказал) всего 50 тыс записей, я и посчитал излишним и подтверждение после "каждых стольких-то". Так как 50 тыс для IB - цифра, допускающая откатить всю вставку, а логика обработки ошибок в его случае может требовать такого отката (например, если в условии задачи - не потерять ни один файл при импорте, если что-то не так - отменить весь импорт, откатив транзакцию, разобраться и попробовать импорт вновь). Могу добавить еще одну вещь. Если уж гнаться за совершенством, то тот код, что я написал, возможно вообще неоптимален. Оптимальный и легко в дальнейшем развиваемый код я бы оформил так: var
FilenameParam,
FielSizeParam,
FileCRCParam,
BaseDirParam : TParam;
with TIBSQL.Create(nil) do
try
Transaction := <компонент транзакции>;
if not Transaction.InTransaction then
Transaction.StartTransaction;
SQL.Text := 'INSERT INTO SERVERFT (FILENAME,FILESIZE,FILECRC,BASEDIR)
VALUES(:FILENAME,:FILESIZE,:FILECRC,:BASEDIR)';
FilenameParam := ParamByName('FILENAME');
FielSizeParam := ParamByName('FILESIZE);
FileCRCParam := ParamByName('FILECRC');
BaseDirParam := ParamByName('BASEDIR');
for j := 0 to Res.Count-1 do
begin
FilenameParam.AsString := Res.Filename[j];
FielSizeParam.AsInteger := Res.Res.FileSize[j];
FileCRCParam.AsInteger := Res.FileCRC[j];
BaseDirParam.AsString := Res.BaseDir[j];
ExecQuery;
и т.д.
-
> kaif © (07.10.08 18:13) [34]
> Насчет оптималности подтверждения после каждых 5тыс. мог > бы поспорить, так как конркетно для IB все равно, коммитить > после каждых 5000 или после каждых 50 тыс. Почему, например, > не после каждых 500?
Никто и не говорит про 5 тыс. Вполне вероятно, что лучшим будет вариант одного-единственного коммита в конце всего пакета. Лишь бы не после каждой записи
> MsGuns © (07.10.08 17:39) [32]
> Приведи практический пример, в котором приведенных в [29] > вариантов не хватает для решения задачи
Мы говорим о "возможности решения задачи" или об ее оптимальном решении? Чтобы просто вставлять записи в БД можно вообще не заморачиваться. Тем более что предложенные варианты никаких преимуществ не имеют. Например, по поводу редактирования многострочного документа коммит каждой строки вообще неудобная крайность. Временные таблицы - тоже неправильный подход. Если надо просто залить данные в плоскую таблицу - зачем делать промежуточное хранилище? Что мы этим выиграем?
> Игорь Шевченко © (07.10.08 17:49) [33]
> То есть, ссылочки на ibase.ru не будет, я верно понимаю > ?
Не будет. А вы очевидных решений без ссылочек не принимаете? Жаль. На все случаи в жизни ссылочек не напасешься...
-
DrPass © (07.10.08 18:26) [35]
> Не будет.
Тогда нефиг " > Я понимаю, вы любитель поумничать. Но зачем умничать в тех > областях, в которых вы слабо разбираетесь-то?
"
в IB я чуть-чуть разбираюсь. Это так, к слову
-
-
> Игорь Шевченко © (07.10.08 18:37) [36] > DrPass © (07.10.08 18:26) [35] > > Тогда нефиг " > > в IB я чуть-чуть разбираюсь. Это так, к слову
Очень хорошо. Практика - критерий истины. Согласны? Сделайте так: 1. Табличку в базе (у меня FB 2.1, но думаю, это не принципиально) create table test(a int, b int) 2. Простенькое приложение - две кнопки, мемо, ibdatabase, ibtransaction, ibsql Запрос такой: insert into test(a, b) values (:a, :b) 3. Ну и соответственно код: procedure TForm1.Button1Click(Sender: TObject);
var
i: integer;
a, b: cardinal;
begin
a:= GetTickCount;
IBTransaction1.StartTransaction;
for i := 0 to 10000 - 1 do
begin
IBSQL1.ParamByName('a').Value:= random(1000);
IBSQL1.ParamByName('b').Value:= random(1000);
IBSQL1.ExecQuery;
end;
IBTransaction1.Commit;
b:= GetTickCount;
Memo1.Lines.Add(inttostr(b - a));
end;
procedure TForm1.Button2Click(Sender: TObject);
var
i: integer;
a, b: cardinal;
begin
a:= GetTickCount;
for i := 0 to 10000 - 1 do
begin
IBTransaction1.StartTransaction;
IBSQL1.ParamByName('a').Value:= random(1000);
IBSQL1.ParamByName('b').Value:= random(1000);
IBSQL1.ExecQuery;
IBTransaction1.Commit;
end;
b:= GetTickCount;
Memo1.Lines.Add(inttostr(b - a));
end; У меня в первом случае (запускал по пять раз): 422 453 438 422 421 Во втором: 9719 9797 9641 9891 10171 Как по-вашему, есть разница - делать коммит после каждой записи, или нет?
-
> DrPass © (07.10.08 19:01) [38]
Да не надо ему ничего объяснять. Если бы ему действительно было интересно, он бы давно набрал "массовая вставка" в поиске на ibase.ru и изучил бы тему... А на самом деле Игорь занимается любимым делом - занудством :) Конечно же позанудствовать можно и даже бывает нужно. Но чувство меры не должно отказывать...
|