powered by simpleCommunicator - 2.0.37     © 2025 Programmizd 02
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Скорость заполнения FDMemTable
10 сообщений из 10, страница 1 из 1
Скорость заполнения FDMemTable
    #40089487
BowMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Заполняю таблицы 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
Скорость заполнения FDMemTable
    #40089489
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
600000+ это миллионы записей с сотнями полей?
...
Рейтинг: 0 / 0
Скорость заполнения FDMemTable
    #40089562
Michael Longneck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В качестве идеи

Код: 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
Скорость заполнения FDMemTable
    #40089585
delphinotes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BowMaster,

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

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

delphinotes
BowMaster,

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

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

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

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

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

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


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

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

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


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