Гость
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Скорость заполнения FDMemTable / 10 сообщений из 10, страница 1 из 1
08.08.2021, 17:46
    #40089487
BowMaster
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Скорость заполнения FDMemTable
Заполняю таблицы DBGridEh (EhLib) данными. Могут использоваться 2 метода заполнения таблицы (вызываются из разных DLL): 1)запросом к базе данных, 2)получением объекта со списком элементов из чужого модуля. Таблиц может быть от 1 до 3, в основном 2.
В данный момент используется FDMemTable (FireDAC), заполняется таким образом - идет цикл по каждому элементу из списка (TList) и делается:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
for i:=0 to ItemList.Count-1 do begin
...
Insert;
Fields[<Идентификатор поля>].AsFloat:=<Название поля класса источника информации>;
...
end; //Завершили цикл по таблице
Post;



Полей в таблице бывает свыше сотни. Понимаю, что если бы использовалось FieldByName это могло замедлить работу, но в данном случае идет обращение по номеру поля.
Для примера, при проверке работы на 600000+ элементов, на слабой машине (Intel Core2 Duo) заполнение идет более часа. Разумеется используется DisableControls. Можно ли как-то ускорить сие действие? Можно разбить заполнение таблиц на параллельные потоки, скажем 2 таблицы - 2 потока, но кажется вряд ли это сильно ускорит дело. Там прикручен прогрессбар и подписывается сколько элементов из скольких заполнено. Судя по всему, скорость заполнения постепенно снижается(вначале куда шустрее заполняется чем под конец). ОЗУ вроде хватает судя по диспетчеру задач, загрузка ЦП 60%+.
...
Рейтинг: 0 / 0
08.08.2021, 17:52
    #40089489
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Скорость заполнения FDMemTable
600000+ это миллионы записей с сотнями полей?
...
Рейтинг: 0 / 0
08.08.2021, 21:35
    #40089562
Michael Longneck
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Скорость заполнения FDMemTable
В качестве идеи

Код: 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.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
procedure FDSetValueToAllRecords(ADataSet: TFDDataSet; const AFieldName: String; const AValue: Variant);
var
  rState: TFDDatSLoadState;
  i, j: Integer;
  oRow: TFDDatSRow;
  oColumn: TFDDatSColumn;
  Fields: TList<TField>;
  bArray: Boolean;
  vValueToSet: Variant;
begin
  bArray := VarIsArray(AValue);

  Fields := TList<TField>.Create;
  try
    ADataSet.GetFieldList(Fields, AFieldName);
    ADataSet.Table.BeginLoadData(rState, lmHavyLoading);
    try
      for i := 0 to Fields.Count - 1 do
      begin
        oColumn := ADataSet.Table.Columns.ColumnByName(Fields[i].FieldName);
        for j := 0 to ADataSet.Table.Rows.Count - 1 do
        begin
          oRow := ADataSet.Table.Rows[j];
          if not (oRow.RowState in [rsInserted, rsModified, rsUnchanged]) then
            Continue;

          if bArray then
            vValueToSet := AValue[i]
          else
            vValueToSet := AValue;

          if not VarSameValue(oRow.ValueO[oColumn], vValueToSet) then
          begin
            oRow.BeginEdit;
            try
              oRow.SetData(oColumn, vValueToSet);
            finally
              oRow.EndEdit;
            end;
          end;
        end;
      end;
    finally
      ADataSet.Table.EndLoadData(rState);
    end;
  finally
    Fields.Free;
  end;
end;
...
Рейтинг: 0 / 0
08.08.2021, 22:42
    #40089585
delphinotes
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Скорость заполнения FDMemTable
BowMaster,

а) перед циклом выполнить:
FDMemTable.Table.Rows.Capacity := ItemList.Count;
б) Insert заменить на Append
в) посмотрите под отладчиком, что там (внутри FD) делается в методе .Post, наверняка индексы перестраиваются и всякое такое, и наверняка это можно отключить и выполнить один раз в конце.
...
Рейтинг: 0 / 0
09.08.2021, 00:36
    #40089594
BowMaster
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Скорость заполнения FDMemTable
rgreat
600000+ это миллионы записей с сотнями полей?

Это сотни тысяч записей с, в среднем, где-то 80 полей, в одной таблице например 120 полей, в другой 40.

delphinotes
BowMaster,

а) перед циклом выполнить:
FDMemTable.Table.Rows.Capacity := ItemList.Count;
б) Insert заменить на Append
в) посмотрите под отладчиком, что там (внутри FD) делается в методе .Post, наверняка индексы перестраиваются и всякое такое, и наверняка это можно отключить и выполнить один раз в конце.

Везде пишут что Insert быстрее Append. Post если обратили внимание делается 1н раз для каждой таблицы, после всего цикла ее заполнения.
...
Рейтинг: 0 / 0
09.08.2021, 00:49
    #40089595
BowMaster
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Скорость заполнения FDMemTable
Michael Longneck,

С этой идеей я сходу не разобрался, ускорение будет за счет того, что не используется метод Insert?

В общем, попробую разные варианты, сообщу о результатах.
...
Рейтинг: 0 / 0
09.08.2021, 02:52
    #40089601
northener
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Скорость заполнения FDMemTable
BowMaster

Везде пишут что Insert быстрее Append. Post если обратили внимание делается 1н раз для каждой таблицы, после всего цикла ее заполнения.

Ну да, ну да. Это вы сами вызываете Post ручками только 1н раз. Но каждый Insert или Append тоже это делает.
А иначе СУБД работать не может.
Записи в БД это не строки в простом "документе"! (Черт бы побрал Билла и его фирму, которая стала делать ОС для кухарок и троешников. Хотя и троешники тоже виноваты.) Это вы в простом документе можете добавить 100500 строк и только после этого сохранить документ в измененном виде.
P.S. Ну доколе ещё мы будем разбирать вопросы связанные с процедурами, которые нужно было забыть ещё в прошлом веке?
...
Рейтинг: 0 / 0
09.08.2021, 08:23
    #40089618
Michael Longneck
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Скорость заполнения FDMemTable
BowMasterС этой идеей я сходу не разобрался, ускорение будет за счет того, что не используется метод Insert?


За счёт использования внутренних структур FireDac, минуя стандартную механику TDataSet
...
Рейтинг: 0 / 0
09.08.2021, 08:37
    #40089620
cptngrb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Скорость заполнения FDMemTable
.
...
Рейтинг: 0 / 0
10.08.2021, 14:54
    #40089875
black-manatee
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Скорость заполнения FDMemTable
Как я понимаю, Вам заполнить FDMemTable нужно только для того, чтобы визуально просматривать ее в таблице.

Если просто вставить 600000 записей в FDMemTable с одним полем ID, в котором будет номер строки от 1 до 600000, то это займет пару секунд даже на небыстрой машине.

Соответственно сделайте одно поле ID и необходимое количество Calculate полей.
Вставьте необходимое количество записей в FDMemTable, где ID будет номер строки.
Ну а в OnCalculate заполняйте поля нужными значениями из List-а. То есть Ваша табличка отобразила 30 записей, которые поместились на экране, соответственно OnCalculate отрисует нужное число полей, а заполнять все поля таблицы не обязательно.
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Скорость заполнения FDMemTable / 10 сообщений из 10, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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