powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Что быстрее?
25 сообщений из 67, страница 2 из 3
Что быстрее?
    #39409575
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrush> На момент написания поста из 2,4млн записей
akrush> за 18 минут обработано только 600тыс.

Ну, 600тыс за 18 минут это, конечно,
жутко медленно, но это значит, что
твои 10 лямов зальются за 5 часов.

Всяко быстрее, чем ты будешь что-то
своё пытаться наварганить. Если цель
"побыстрее", а не "научиться", конечно.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Что быстрее?
    #39409576
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad,

Возможно, если сгенерить execute block с тысячей-другой инсертов внутри, было бы быстрее. Хотя не факт и надо пробовать, если хочется ускорить.
...
Рейтинг: 0 / 0
Что быстрее?
    #39409579
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов Рустам,
цели 2:
1. ОСНОВНАЯ - побыстрее, т.к. у меня уже 20 баз на такую операцию и ждать даже 3 часа - долго
2. В чем-то научиться обрабатывать большие массивы данных, чтобы на будущее уже не играться "как лучше и быстрее", а делать быстро и качественно.
...
Рейтинг: 0 / 0
Что быстрее?
    #39409599
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockВозможно, если сгенерить execute block с тысячей-другой инсертов внутриОграничение на 255 контекстов на запрос никто не отменял.

В любом случае, препарированный инсерт не может быть медленнее скрипта с инсертами.
...
Рейтинг: 0 / 0
Что быстрее?
    #39409604
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrush> 1. ОСНОВНАЯ - побыстрее, т.к. у меня уже 20 баз на такую операцию

Тогда вариантов нет, только Query с параметрами, Prepare,
в цикле заполнение параметров + Execute, и коммит через
каждые условные "100 тыс."
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Что быстрее?
    #39409608
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvladYuRockВозможно, если сгенерить execute block с тысячей-другой инсертов внутриОграничение на 255 контекстов на запрос никто не отменял.

В любом случае, препарированный инсерт не может быть медленнее скрипта с инсертами.
Да, но так сетевых запросов больше в N раз. На локальном соединении, бесспорно, препарированный инсерт должен быть быстрее.
...
Рейтинг: 0 / 0
Что быстрее?
    #39409610
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock,

это ты сейчас меня агитируешь за EXEC BLOCK с пачкой инсертов ?
Давай вспомним - откуда он вообще взялся и что было одной из причин его появления :)

PS А кто мешает EXEC BLOCK с параметрами делать ?
PPS ТС-у это явно не по силам в данный момент, не стоит его путать ещё больше
...
Рейтинг: 0 / 0
Что быстрее?
    #39409638
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad,

Да никого я не собирался агитировать, тем более тебя)
EB нужен не для этого, понятно, а для "одноразового" psql без создания процедуры.
ТСу в данной задаче он не нужен, конечно.
Всё, лучше б я не начинал)
...
Рейтинг: 0 / 0
Что быстрее?
    #39409662
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов Рустам,
влад, если я правильно его понял, так и советовал. Закончу со скриптом и обязательно проверю с квериком
...
Рейтинг: 0 / 0
Что быстрее?
    #39409665
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
о скорости вставки обязательно сообщу.
Если работой отвлекать не будут - в понедельник уже скажу результат, а может и раньше
...
Рейтинг: 0 / 0
Что быстрее?
    #39409700
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockEB нужен не для этого, понятно, а для "одноразового" psql без создания процедуры.
ТСу в данной задаче он не нужен, конечно.Почему же - не для "этого" ? И для "этого" тоже !

Надеюсь, мы одно и то же "это" имеем в виду :)


YuRockВсё, лучше б я не начинал)Всяко лучше Дилиных вывертов, как по мне ;)
...
Рейтинг: 0 / 0
Что быстрее?
    #39409707
Фотография Di_LIne
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvladВсяко лучше Дилиных вывертов, как по мне ;)
Давно бы сваял онлайн транслятор с русского на SQL.
...
Рейтинг: 0 / 0
Что быстрее?
    #39409726
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Di_LInehvladВсяко лучше Дилиных вывертов, как по мне ;)
Давно бы сваял онлайн транслятор с русского на SQL. Механизировать искусство ? Нет уж :-)

PS Но меру знать всё равно надо.
PPS Посему - завязываем
...
Рейтинг: 0 / 0
Что быстрее?
    #39409731
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockДа, но так сетевых запросов больше в N раз.
Влад сказал про контексты, а не про коннекты.

А если отвлечься в сторону параллельной вставки в одну таблицу, то она всегда медленнее, чем вставка в одну таблицу одним коннектом. Разве что суперсервер в ФБ 3.0 показывает масштабирование, с некоторым просадом относительно "монопольной вставки".
Не помню, публиковал я статью на эту тему или нет, на выходных найду, выложу сюда.
...
Рейтинг: 0 / 0
Что быстрее?
    #39409835
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если кому-то все еще интересно. Результаты теста на скорость вставки.
Имеем:
Есть старые данные по отчетам (которые формировались ежемесячно) и новые данные по отчетам (были сформированы заново после исправления в программе ошибки).

Ноутбук Lenovo G50-80, i7 2.4-3.0Gh, RAM 4Gb, SSD 512Gb, HDD 1Tb
Windows 10 Pro, Firebird 3.0 (default config)
База данных: размер страницы 16384
База данных находится на разделе HDD у которого размер блока тоже 16384
Среда разработки: Delphi XE2 + FIBPlus 7.4

Исходные файлы DBF находят на SSD:
старая информация - объем файлов 1 244 796 733 байт, 927 файлов, Количество записей - 2 442 537
новая информация - 1 245 382 545 байт, 923 файла, Количество записей - 2 443 703

Так как обработку провожу программно принял решение не терять время на объединение всех DBF в один файл (как для Эксперта), а загрузка ведется сразу из каждого DBF.
Загрузка идет в 2 таблицы в БД. Таблицы по структуре одинаковые, индекс не отключался.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
CREATE TABLE RJ_NEW (
    CODE    INTEGER,
    FMONTH  INTEGER,
    FYEAR   INTEGER,
    RASH    VARCHAR(15),
    NUMB    BIGINT,
    DAT1    DATE,
    DAT2    DATE,
    SM1     DECIMAL(9,2),
    SM2     DECIMAL(9,2),
    SM3     DECIMAL(9,2),
    SM4     DECIMAL(9,2),
    SM5     DECIMAL(9,2),
    SM6     DECIMAL(9,2),
    SM7     DECIMAL(9,2),
    SM8     DECIMAL(9,2),
    SUMMA   DECIMAL(9,2)
);
CREATE INDEX IDX_RJ_NEW ON RJ_NEW (CODE, NUMB);




Тест № 1.
Использование FIBScripter. Формируется скрипт на вставку значений вида
insert into RJ_NEW(fields...) values (значения);
каждые 50тыс. в скрипт добавляется команда commit и скрипт запускается на выполнение.
После выполнения очистка и так далее.
Результат:
-----===== Начинаем обработку (8:35:49) =====-----
-----===== Закончили обработку (8:53:51) =====-----
Итого: 00:18:02

Тест № 2.
Использование FIBQuery. Внутри запрос с параметрами на вставку вида
insert into RJ_NEW(fields...) values (параметры);
После присвоения значений параметров выполнялся Prepare;
каждые 50тыс. - CommitRetaining;
-----===== Начинаем обработку (9:58:39) =====-----
-----===== Закончили обработку (10:08:48) =====-----
итого: 00:10:09

Тест № 3.
Тоже самое что и "Тест № 2", но без Prepare после присвоения значений параметров.
-----===== Начинаем обработку (10:09:41) =====-----
-----===== Закончили обработку (10:19:55) =====-----
00:10:14

Единственная погрешность которая может быть: Тест 1 выполнялся при активном приложении, а тест 2 и 3 - выполнялись в фоне (я работал в других приложениях), но думаю погрешность будет не большая.

Большое спасибо всем за подсказки.
По сравнению с IBExpert в любом тесте прирост скорости очевиден. Думаю что можно попробовать еще чуть-чуть ускорить если отключить индекс.
Отдельное спасибо Владу за подсказку про FIBQuery, забыл совсем про него.
Результат очевиден:
Если вставка делается более 2-3 раз, и есть возможность, лучше написать программку на вставку, если разово - однозначно IBExpert.
Как говорится - "лучше день потерять, потом за пять минут долететь." (Союзмультфильм, Крылья, ноги и хвосты)
...
Рейтинг: 0 / 0
Что быстрее?
    #39409838
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Забыл написать - конект к БД локальный, только путь к файлу
...
Рейтинг: 0 / 0
Что быстрее?
    #39409874
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrushПосле присвоения значений параметров выполнялся Prepare;
То есть ты совершенно не понимаешь что именно делает Prepare и для чего он нужен.

akrushкаждые 50тыс. - CommitRetaining;
То есть ты совершенно не понимаешь что делает CommitRetaining и тупо делаешь как сказал
кто-то на форуме.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Что быстрее?
    #39409885
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,
Подскажите, буду знать и учту на будущее
...
Рейтинг: 0 / 0
Что быстрее?
    #39409899
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
API Reference читай.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Что быстрее?
    #39409944
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrush> Тест № 2.
> Использование FIBQuery. Внутри запрос с параметрами на вставку вида
> После присвоения значений параметров выполнялся Prepare;
> каждые 50тыс. - CommitRetaining;

Ну то есть ты понял довольно мало, хотя тебе два
человека пошагово рассказали. Мог бы хоть статьи
или предыдущие обсуждения почитать.

Ну и код свой привести, чтобы тебе его исправили.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
var cnt : integer;
...
cnt := 0;
Query.SQL.Text := 'INSERT INTO T1(field1, field2, ...) VALUES(:param1, :param2, ...)';
UTransaction.StartTransaction;
Query.Preapre;

try
  while Not DBF.End do
  begin
    Query.Params[0].Value/AsType := DBF.Field[0].Value/AsType; // или через ParamByName
    Query.Params[1].Value/AsType := DBF.Field[1].Value/AsType; // или через ParamByName
    ...
    Query.ExecQuery;
    Inc(cnt);
    if (cnt = 100 000) then
    begin
      UTransaction.Commit;
      UTransaction.StartTransaction;
      cnt := 0;
      // update прогресс-бара если нужно
    end;
except
  // логирование
  UTransaction.Rollback;
end;
// вообще-то нужно ещё finally с UTransaction.Rollback, но это по вкусу



C двумя таблицами аналогично - либо добавится второй
Query рядом, либо делай процедуру, в которую будешь
передавать всё одним запросом, а она будет рассовывать.

Хотя, судя по цифрам, не думаю, что прирост скорости
будет сколько-нибудь значительным. Ну и если заливка -
процесс монопольный, в пустую таблицу и каждый раз по
10 лямов - да, можно все индексы отключать/включать.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Что быстрее?
    #39409948
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов Рустам,
Свой код - как-то не подумал. Пока писал пост с результатами - начали отвлекать работой.
Вот код процедуры на втягивание старой информации.
Советы принимаются с ОГРОМНОЙ РАДОСТЬЮ

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
Procedure TFMain.LoadFromOLD;
var
  FlIni:TIniFile;
  FlInCount, i, j, c:Integer;
  InPath:String;
begin
  MemoRep.Lines.Add('Початок читання OLD: '+TimeToStr(Time));
  if not fbDBPerelik.Connected then fbDBPerelik.Connected:=True;
  PrBarAll.Position:=0;
  c:=0;
  FileListBox:=TStringList.Create();
  FlIni:=TIniFile.Create(ExtractFileDir(paramstr(0))+'\Options.ini');
  FlInCount:=FlIni.ReadInteger('PERELIK_OLD','count',0);
  if FlInCount=0 then Exit;
  fbScript.Script.Clear;
  fbScript.Script.Add('delete from rj_old;');
  fbScript.Script.Add('commit;');
  fbScript.ExecuteScript();
  fbQOld.Transaction.StartTransaction;
  for i:=1 to FlInCount do
    begin {FlInCount}
      InPath:=FlIni.ReadString('PERELIK_OLD','FilePath'+inttostr(i),'');
      if copy(InPath,length(InPath),1)='\'
        then InPath:=copy(InPath,1,length(InPath)-1);
      GetAllFiles(InPath+'\',FileListBox);
      TInDBF.FilePath:=InPath;
      PrBarAll.Max:=FileListBox.Count-1;
      for j:=0 to FileListBox.Count-1 do
        begin {FileListBox.Count}
          PrBarAll.Position:=PrBarAll.Position+1;
          if UpperCase(ExtractFileExt(FileListBox.Strings[j]))=UpperCase('.dbf')
            then
              begin {Check extention}
                TInDBF.TableName:=FileListBox.Strings[j];
                TInDBF.Open;
                PrBarFiles.Position:=0;
                PrBarFiles.Max:=TInDBF.RecordCount;
                while not TInDBF.Eof do
                  begin {while not TInDBF.Eof do}
                    PrBarFiles.Position:=PrBarFiles.Position+1;
                    Application.ProcessMessages;
                    fbQOld.ParamByName('code').Value:=
                                 (StrToInt(copy(TInDBF.TableName,1,4)));
                    fbQOld.ParamByName('fmonth').Value:=
                                 (StrToInt(copy(TInDBF.TableName,5,2)));
                    fbQOld.ParamByName('fyear').Value:=
                                 (StrToInt(copy(TInDBF.TableName,7,2)));
                    fbQOld.ParamByName('rash').Value:=
                                            TInDBF.FieldByName('RASH').AsString;
                    fbQOld.ParamByName('numb').Value:=
                                            TInDBF.FieldByName('NUMB').AsInteger;
                    fbQOld.ParamByName('dat1').Value:=
                               DateToStr(TInDBF.FieldByName('DAT1').AsDateTime);
                    fbQOld.ParamByName('dat2').Value:=
                               DateToStr(TInDBF.FieldByName('DAT2').AsDateTime);

                    if (length(TInDBF.FieldByName('SM1').AsString)=0)
                       or(TInDBF.FieldByName('SM1').AsString=' ')
                      then fbQOld.ParamByName('sm1').Value:=0
                      else fbQOld.ParamByName('sm1').Value:=
                                  (TInDBF.FieldByName('SM1').AsFloat);

                    if (length(TInDBF.FieldByName('SM2').AsString)=0)
                       or(TInDBF.FieldByName('SM2').AsString=' ')
                      then fbQOld.ParamByName('sm2').Value:=0
                      else fbQOld.ParamByName('sm2').Value:=
                                 (TInDBF.FieldByName('SM2').AsFloat);

                    if (length(TInDBF.FieldByName('SM3').AsString)=0)
                       or(TInDBF.FieldByName('SM3').AsString=' ')
                      then fbQOld.ParamByName('sm3').Value:=0
                      else fbQOld.ParamByName('sm3').Value:=
                                            (TInDBF.FieldByName('SM3').AsFloat);

                    if (length(TInDBF.FieldByName('SM4').AsString)=0)
                       or(TInDBF.FieldByName('SM4').AsString=' ')
                      then fbQOld.ParamByName('sm4').Value:=0
                      else fbQOld.ParamByName('sm4').Value:=
                                           (TInDBF.FieldByName('SM4').AsFloat);

                    if (length(TInDBF.FieldByName('SM5').AsString)=0)
                       or(TInDBF.FieldByName('SM5').AsString=' ')
                      then fbQOld.ParamByName('sm5').Value:=0
                      else fbQOld.ParamByName('sm5').Value:=
                                            (TInDBF.FieldByName('SM5').AsFloat);

                    if (length(TInDBF.FieldByName('SM6').AsString)=0)
                       or(TInDBF.FieldByName('SM6').AsString=' ')
                      then fbQOld.ParamByName('sm6').Value:=0
                      else fbQOld.ParamByName('sm6').Value:=
                                            (TInDBF.FieldByName('SM6').AsFloat);

                    if (length(TInDBF.FieldByName('SM7').AsString)=0)
                       or(TInDBF.FieldByName('SM7').AsString=' ')
                      then fbQOld.ParamByName('sm7').Value:=0
                      else fbQOld.ParamByName('sm7').Value:=
                                        (TInDBF.FieldByName('SM7').AsFloat);

                    if (length(TInDBF.FieldByName('SM8').AsString)=0)
                       or(TInDBF.FieldByName('SM8').AsString=' ')
                      then fbQOld.ParamByName('sm8').Value:=0
                      else fbQOld.ParamByName('sm8').Value:=
                                           (TInDBF.FieldByName('SM8').AsFloat);

                    if (length(TInDBF.FieldByName('SUMMA').AsString)=0)
                       or(TInDBF.FieldByName('SUMMA').AsString=' ')
                      then fbQOld.ParamByName('summa').Value:=0
                      else fbQOld.ParamByName('summa').Value:=
                                     (TInDBF.FieldByName('SUMMA').AsFloat);
                    fbQOld.ExecQuery;
                    c:=c+1;
                    if c mod 50000=0 then fbQOld.Transaction.CommitRetaining;
                    TInDBF.Next;
                  end; {while not TInDBF.Eof do}
                 TInDBF.Close;
              end; {Check extention}
        end;  {filelistbox.count}
    end; {filecount}
  fbQOld.Transaction.Commit;
  fbQOld.Close;
  FlIni.Free;
  FileListBox.Free;
  if fbDBPerelik.Connected then fbDBPerelik.Connected:=False;
  MemoRep.Lines.Add('Завершили читання OLD: '+TimeToStr(Time));
  MemoRep.Lines.Add('Кількість записів OLD: '+IntToStr(c));
  MemoRep.Lines.Add('');
end;




Код уже не исправлял по замечаниям Dimitry Sibiryakov, но как я понял вместо
fbQOld.Transaction.CommitRetaining;
нужно
begin
fbQOld.Transaction.Commit;
fbQOld.Transaction.StartTransaction;
end;
...
Рейтинг: 0 / 0
Что быстрее?
    #39409949
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrush,
Проверки полей sm1-sm8, summa выглядит смешно, но пришлось сделать так как народ, не понятно каким редактором, вносил изменения и теперь в этих полях может быть или пусто или пробел
...
Рейтинг: 0 / 0
Что быстрее?
    #39410065
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrush,

1. Убери скрипт) выполни delete тоже через ExecQuery. И коммит не через скрипт)
2. Убери ProcessMessages или хотябы перенеси его под if mod 50000 = 0. Станет быстрее.
3. Для полей sum* сделай фцию DBFStrToFloat, передавай в нее имя поля, а внутни нее уже этот страшный иф. Невозможно ж смотреть на это.
...
Рейтинг: 0 / 0
Что быстрее?
    #39410095
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock,
1 и 2 сделаю спасибо.
3 - можно, конечно будет легче смотреть. Просто делал на скорую руку, и проверки писались по мере того как нарывался на "грабли".
...
Рейтинг: 0 / 0
Что быстрее?
    #39410101
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrush будет легче смотреть. Просто делал на скорую руку, и проверки писались по мере того как нарывался на "грабли".Не только смотреть. Копипаст - это еще одни грабли.
...
Рейтинг: 0 / 0
25 сообщений из 67, страница 2 из 3
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Что быстрее?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]