Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > БД в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 30.10.2019, 09:26   #1
Heneken87
Форумчанин
 
Регистрация: 27.04.2012
Сообщений: 219
По умолчанию Реализация фильтра на базе TFDMemTable

Доброго времени суток. Занимаюсь рефакторингом кода и вот наткнулся на модуль, который писал лет 100 тому назад. Хотелось бы ускорить его работу. Может кто-то уже сделал что-то подобное гораздо красивее и качественнее.

Модуль предназначен для отображения средствами TDataSource,TDBGrid датасетов (TFDMemTable,TFdStoredProc,TfdQuery ) с предоставлением визуального интерфейса для фильтрации этого набора данных. (по клику на колоночку, как в Excel выскакивает чеклист). Собственно заполнение самого чеклиса сделано топорно и вот что мне не нравиться:
1 - Сначало я делаю реплику датасета:
Код:
   FMyDbGrid.BuferMem.Data :=BuferQuery.Data; (TDataSource,TDBGrid привязаны к BuferQuery)
Это сделано только с 1 целью, чтобы при манипуляциях с полученным набором визуально ничего не менялось.
2 - На событии клика по заголовку в DbGrid пробегаю циклом по
FMyDbGrid.BuferMem и заполняю TStringList так:
Код:
  // ListStart это TStringList
  Bdata := BuferMem.FieldByName(AName).AsString;
  if FormFilterMyGrid.ListStart.IndexOf(Bdata) < 0 then
  FormFilterMyGrid.ListStart.AddObject(Bdata,TObject(Bdata));
И вот тут,на таблицах в 20-30 тыс строк, приходится ждать порядка 10-20 секунд.

Хочется:
1 - Избавится от BuferMem вообще
2 - Выполнить чтение сразу из BuferQuery, при этом не менять RecNo от слова совсем
3 - Связан с пунктом 2. Максимально быстро передать значения в TStringList.

Я пока вижу только подобную реализацию, может у кого есть другие, более грамотные идеи или уже что-то реализованное. Спасибо.

P:S: Добавлю. Я реализовывал подобный фильтр в другом модуле. Там тоже был цикл, но он был по массиву. Цикл по 500 тыс строк и добавлением их в TStringList занимал порядка 10-11 секунд, что в 10 раз быстрее фильтра из примера. Поэтому сколоняюсь к тому, что основные тормоза идут при смене RecNo в датасете, поскольку реализация там далеко не "Inc(RecNo)". Я думаю, что решением этой проблемы будет следующиее- докопаться до самого массива данных или до памяти, но с пол пинка это не сделать. Поэтому Help =)
Пишу много и развернуто

Последний раз редактировалось Heneken87; 30.10.2019 в 09:57.
Heneken87 вне форума Ответить с цитированием
Старый 30.10.2019, 09:58   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

А подготовить эти стринглисты один раз при входе в программу. То ли на клиенте чтением датасета без отображения в гриде процесса, то ли запросами с distinct или group by. Что быстрей выяснить экспериментально.

add если динамически это делать, то есть DisableControls и EnableControls у датасета для блокировки изменения отображения в контролах. Но тормоза все равно будут при заполнении стриглиста
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 30.10.2019 в 10:04.
Аватар вне форума Ответить с цитированием
Старый 30.10.2019, 10:06   #3
Heneken87
Форумчанин
 
Регистрация: 27.04.2012
Сообщений: 219
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
А подготовить эти стринглисты один раз при входе в программу. То ли на клиенте чтением датасета без отображения в гриде процесса, то ли запросами с distinct или group by. Что быстрей выяснить экспериментально.
Готовить TStringList заранее точно исключено. По факту модуль был написан для работы с справочными таблицами. Их очень много и скорей всего получу на половине OutOfMemory. Запорсами будет быстрее, но если есть хоть какая то возможность снизить нагрузку на БД, лучше попытаться сделать это локально.
Пишу много и развернуто
Heneken87 вне форума Ответить с цитированием
Старый 30.10.2019, 10:11   #4
Heneken87
Форумчанин
 
Регистрация: 27.04.2012
Сообщений: 219
По умолчанию

Конечно я поговорю с коллегами, если у нас будет вариант посадить справочную БД на отдельную машину, то Ваше предложение с запросами будет очень прекрасным выходом из ситуации.
Пишу много и развернуто
Heneken87 вне форума Ответить с цитированием
Старый 30.10.2019, 10:21   #5
Heneken87
Форумчанин
 
Регистрация: 27.04.2012
Сообщений: 219
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
DisableControls и EnableControls
Если мне память не изменяет эти флаги запрещают контроль с стороны пользователя и не более. При циклах по датасету позиция меняется в.т.ч и визуально.
Пишу много и развернуто
Heneken87 вне форума Ответить с цитированием
Старый 30.10.2019, 10:26   #6
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

Цитата:
Сообщение от Heneken87 Посмотреть сообщение
Если мне память не изменяет эти флаги запрещают контроль с стороны пользователя и не более. При циклах по датасету позиция меняется в.т.ч и визуально.
а по моему Вы ошибаетесь.
DisableControls как раз и запрещает визуальным контролам отображать изменения состояния.


http://docs.embarcadero.com/products...eControls.html
Цитата:
Call DisableControls prior to iterating through a large number of records in the dataset to prevent data-aware controls from updating every time the active record changes. Disabling controls prevents flicker and speeds performance because data does not need to be written to the display.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 30.10.2019, 10:29   #7
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

Цитата:
Сообщение от Heneken87 Посмотреть сообщение
Их очень много и скорей всего получу на половине OutOfMemory
Зачем для всех сразу? Они же одновременно все не просматриваются. А только одна, вот для неё и готовить предварительно в момент входа на её просмотр. Кстати у грида из ehlib предусмотрена фильтрация похожая на excel, но если записей очень много будут те же тормрза при формирования списка значений
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 30.10.2019 в 10:32.
Аватар вне форума Ответить с цитированием
Старый 30.10.2019, 10:32   #8
Heneken87
Форумчанин
 
Регистрация: 27.04.2012
Сообщений: 219
По умолчанию

Господа. Я поторопился =). Проблема решена и была в другом. Спасибо Аватар, я обратил внимание на фразу "о тормоза все равно будут при заполнении стриглиста".
Решение до безобразие простое:
Из кода убрано
Код:
if FormFilterMyGrid.ListStart.IndexOf(Bdata) < 0 then
В свойства листа проставлено:
Код:
   FormFilterMyGrid.ListStart.Sorted := True;
   FormFilterMyGrid.ListStart.Duplicates := dupIgnore;
Все. 15к записей за 0.3 секунды =))) Тему можно закрывать. Поспешишь - народ насмешишь
Пишу много и развернуто
Heneken87 вне форума Ответить с цитированием
Старый 30.10.2019, 11:47   #9
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

Цитата:
Сообщение от Heneken87 Посмотреть сообщение
Тему можно закрывать.
Это хорошо.


Цитата:
Сообщение от Heneken87 Посмотреть сообщение
if FormFilterMyGrid.ListStart.IndexOf( Bdata) < 0 then
просто отмечу, что для поиска в сортированном TStringList можно использовать быстрый метод Find()
Serge_Bliznykov вне форума Ответить с цитированием
Старый 30.10.2019, 12:09   #10
Heneken87
Форумчанин
 
Регистрация: 27.04.2012
Сообщений: 219
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
просто отмечу, что для поиска в сортированном TStringList можно использовать быстрый метод Find()
Спасибо, если найдутся баги при текущем способе вставки уникальных значений, то воспользуюсь.
Пишу много и развернуто
Heneken87 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Реализация системы поиска по базе данных cyg Microsoft Office Access 0 19.03.2017 12:20
Реализация фильтрации в базе данных SQL в ASP.NET dridnol Помощь студентам 0 22.06.2012 09:20
Реализация контейнера на базе очереди. Delphi medvedeva Помощь студентам 0 26.06.2011 13:36
Автосигнализация на базе MC-51, реализация проверки правильности кода Lesha_maestro Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 0 23.05.2010 17:08