Начало » Использование СУБД » Firebird, HQbird, InterBase » IBX: буферизация записей
IBX: буферизация записей [сообщение #1401] |
Fri, 20 January 2023 11:21 |
|
Док
Сообщений: 101 Зарегистрирован: June 2022
|
Senior Member |
|
|
Решил отказаться от использования сетки и перейти на VTV для отображения данных. Почитал еще раз Димину статью http://www.ibase.ru/ibx/#ibdataset
Хотелось бы уяснить для себя несколько моментов. За комментарии и уточнения буду благодарен.
Начальные условия: используется IBQuery (без присоединенных к нему dbaware-компонентов), и записей в таблице больше или кратно равно размеру BufferChunks у компонента.
Правильно ли я понимаю, что:
1. после открытия IBQuery, если сделать IBQuery.FetchAll или IBQuery.AutoFetchAll = True, то отфетчится BufferChunks записей)?
2. при фетче следующих BufferChunks записей предыдущие выкидываются из буфера и не "плюсуются" к свежеотфетченным? А если понадобится отыскать запись из предыдущего фетча при помощи Locate, то тоже фетчится BufferChunks записей, первой из которых будет искомая запись?
3. IBQuery.First всегда фетчит первые BufferChunks записей, а потом переходит к RecNo = 1?
4. IBQuery.Last всегда фетчит в буфер датасета последние BufferChunks записей, а потом переходит к RecNo = RecordCount?
5. при первом фетче (после открытия датасета) BOF = True, если IBQuery.First, при переходе к следующей записи (IBQuery.Next) BOF = False? Если фетч не первый, то для RecNo = 1 BOF = False?
И еще,
в каких случаях при переходе к RecNo = RecordCount я получу EOF = True:
6. RecordCount < BufferChunks?
7. RecordCount = BufferChunks (при условии, что RecNo = RecordCount и является последней в табличке на сервере, т.е. все записи влезли "тютелька-в тютельку")?
Вопросов много, но смогу задать по мере осмысления ситуации
FPC/Lazarus (trunk) | Win10 x64 Ultim/Debian 11 amd64/Darwin x86_64 Monterey | Firebird 3.0.10 x64 | IBX by TonyWhyman
https://zoltanleo.blogspot.com/
|
|
|
Re: IBX: буферизация записей [сообщение #1403 является ответом на сообщение #1401] |
Fri, 20 January 2023 11:51 |
kdv
Сообщений: 98 Зарегистрирован: June 2022
|
Member |
|
|
про BufferChunks - это просто буфер (блок) для считывания пачек записей. Т.е. кусок, НА который увеличивается кэш датасета при очередном fetch, если bufferchunks кончился.
Так что при Fetchall, Last и прочем кэш датасета заполняется целиком, ничего там не выкидывается.
Читаем в bufferchunks, как только он кончился, перекидываем в кэш датасета (плюсуем), и так до конца считывания записей с сервера.
Собственно, про BufferChunks можно просто забыть.
https://docwiki.embarcadero.com/Libraries/Sydney/en/IBX.IBCu stomDataSet.TIBCustomDataSet.BufferChunks
[Обновления: Fri, 20 January 2023 11:53] Известить модератора
|
|
|
|
|
Re: IBX: буферизация записей [сообщение #1408 является ответом на сообщение #1404] |
Fri, 20 January 2023 13:34 |
|
Док
Сообщений: 101 Зарегистрирован: June 2022
|
Senior Member |
|
|
МП писал(а) Fri, 20 January 2023 12:01Док, если ты решил отказаться от dbaware-компонентов, то и наследник датасета (TIBQuery) тебе нахрен не нужен.
он выполняет туеву хучу дополнительных раундтрипов из-за того, что так положено датасету для поддержки dbaware.
пользуй TIBSQL.
TIBSQL я для модифицирующих запросов широко использую, а вот для селективных как-то ни разу не приходилось.
В моем случае, если я заполняю дерево и прикручиваю к нему пагинатор после 100 записей, то получается в цикле надо будет 100 запросов выполнить, предварительно отпрепарировав текст?
А как технически будет выглядеть переход к следующей записи (в табличке на сервере)?
FPC/Lazarus (trunk) | Win10 x64 Ultim/Debian 11 amd64/Darwin x86_64 Monterey | Firebird 3.0.10 x64 | IBX by TonyWhyman
https://zoltanleo.blogspot.com/
[Обновления: Fri, 20 January 2023 13:41] Известить модератора
|
|
|
|
|
|
|
|
Re: IBX: буферизация записей [сообщение #1416 является ответом на сообщение #1412] |
Fri, 20 January 2023 17:38 |
kdv
Сообщений: 98 Зарегистрирован: June 2022
|
Member |
|
|
Док писал(а) Fri, 20 January 2023 15:49
Предполагается, что рут-записей будет много, неужели все грузить (даже в свернутом виде)?
1. нахрена тебе select count. Сделай select корневых записей, потом Last (или fetchall), возьми recordcount.
2. много - это сколько, и зачем вообще в этом случае юзеру их видеть, тем более через "пагинатор". 1 миллион? 100 тыщ? Ставь сразу критерии отбора нормальные.
Ну вот допустим тебе надо деталь какую-то найти автомобильную, у поставщика. Ты что, будешь Locate-ом или еще как продираться через 100 тыщ деталей? Ну никто так не делает.
Вообрази себя на месте пользователя, а не программиста.
|
|
|
Re: IBX: буферизация записей [сообщение #1417 является ответом на сообщение #1416] |
Fri, 20 January 2023 17:44 |
kdv
Сообщений: 98 Зарегистрирован: June 2022
|
Member |
|
|
извиняюсь, прорвало. Вспомнилось, как некто мне на семинаре Эмбаркадеры про приложения на мобилах говорит
- я вот тут в список загрузил 1000 (или 10к) строк, и он тормозит.
Ну ёп... Ты этот список зачем вывел, чтобы что? Чтобы юзер убился, оплевался, и проклял того кто выводит 1000 элементов на экране планшета или мобилы?
Ну допустим, не весь список а "пагинатор" - зачем, для чего, чтобы что?
|
|
|
Re: IBX: буферизация записей [сообщение #1418 является ответом на сообщение #1401] |
Fri, 20 January 2023 17:54 |
kdv
Сообщений: 98 Зарегистрирован: June 2022
|
Member |
|
|
кстати, по поводу RecordCount.
Слава богу, это свойство приводит к "внутреннему" Select count только для IBTable. Остальные датасеты тупо показывают количество отфетченных на текущий момент записей в кэш датасета (IBDataSet, IBQuery). Которые кладутся в буфер датасета (не в BufferChunks). Грубо говоря, Last/FetchAll и RecordCount покажут, сколько всего было выбрано записей "на клиента", в локальный буфер. После чего Next, Prev, First и Last будут елозить по этому буферу, без обращений к серверу, совсем.
|
|
|
Re: IBX: буферизация записей [сообщение #1419 является ответом на сообщение #1417] |
Fri, 20 January 2023 17:55 |
МП
Сообщений: 889 Зарегистрирован: August 2022 Географическое положение: бурятский тун...
|
Senior Member |
|
|
kdvизвиняюсь, прорвало. Вспомнилось, как некто мне на семинаре Эмбаркадеры про приложения на мобилах говорит
- я вот тут в список загрузил 1000 (или 10к) строк, и он тормозит.
Ну ёп... Ты этот список зачем вывел, чтобы что? Чтобы юзер убился, оплевался, и проклял того кто выводит 1000 элементов на экране планшета или мобилы?
Ну допустим, не весь список а "пагинатор" - зачем, для чего, чтобы что? ха!
китайские "индусы" этой заумью не заморачиваются.
ну нету у них нормальных фильтров на АлиБабае.
практически нету.
листай, листай, листай...
п#дарасы!
зы: яндЫкс-маркет тоже уже почти достиг этой нирваны.
|
|
|
Re: IBX: буферизация записей [сообщение #1421 является ответом на сообщение #1418] |
Fri, 20 January 2023 21:57 |
|
Док
Сообщений: 101 Зарегистрирован: June 2022
|
Senior Member |
|
|
kdv писал(а) Fri, 20 January 2023 17:54кстати, по поводу RecordCount.
Слава богу, это свойство приводит к "внутреннему" Select count только для IBTable. Остальные датасеты тупо показывают количество отфетченных на текущий момент записей в кэш датасета (IBDataSet, IBQuery). Которые кладутся в буфер датасета (не в BufferChunks). Грубо говоря, Last/FetchAll и RecordCount покажут, сколько всего было выбрано записей "на клиента", в локальный буфер. После чего Next, Prev, First и Last будут елозить по этому буферу, без обращений к серверу, совсем.
Дим, погоди. Ты щас опять запутаешь.
1. RecordCount показывает, сколько щас записей отфетчено в буфер датасета.
2. IBQuery.Last заставляет фетчить на клиента ВСЕ записи, отвечающие условиям выборки, с сервера
3. IBQuery.Last = IBQuery.FetchAll
4. IBQuery.Locate отфетчит все записи, если искомая запись окажется в выборке последней
Все верно?
ПС. Забудь ты про селект каунт - это мусор от экспериментов в гуе
FPC/Lazarus (trunk) | Win10 x64 Ultim/Debian 11 amd64/Darwin x86_64 Monterey | Firebird 3.0.10 x64 | IBX by TonyWhyman
https://zoltanleo.blogspot.com/
[Обновления: Fri, 20 January 2023 22:11] Известить модератора
|
|
|
|
|
|
|
Re: IBX: буферизация записей [сообщение #1446 является ответом на сообщение #1418] |
Mon, 23 January 2023 05:54 |
fraks
Сообщений: 140 Зарегистрирован: June 2022 Географическое положение: Новосибирск
|
Senior Member |
|
|
kdv писал(а) Fri, 20 January 2023 21:54кстати, по поводу RecordCount.
Слава богу, это свойство приводит к "внутреннему" Select count только для IBTable. Остальные датасеты тупо показывают количество отфетченных на текущий момент записей в кэш датасета (IBDataSet, IBQuery). Которые кладутся в буфер датасета (не в BufferChunks). Грубо говоря, Last/FetchAll и RecordCount покажут, сколько всего было выбрано записей "на клиента", в локальный буфер. После чего Next, Prev, First и Last будут елозить по этому буферу, без обращений к серверу, совсем.
У Дока дерево. Зачем елозить по буферу если оно уже в дерево загружено? Скрипач не нужен.
Делаем запрос корневых записей через TIBSQL, получаем по одной, сразу складываем в дерево.
Если дерево - это VTV и мы не используем DataSet - то все работает быстро, а 10 тысяч записей - это все еще небольшое количество.
У меня 10 тысяч записей в т.ч. с полем varchar(256) тянется с сервера, складывается в мой буфер, отображается в VTV за 0,77сек.
При этом мой буфер не идеален по быстродействию.
Если грузить просто в динамический массив рекордов или сразу в дерево - будет еще быстрее.
[Обновления: Mon, 23 January 2023 05:54] Известить модератора
|
|
|
|
|
|
|
|
Re: IBX: буферизация записей [сообщение #1489 является ответом на сообщение #1478] |
Thu, 26 January 2023 23:56 |
|
Док
Сообщений: 101 Зарегистрирован: June 2022
|
Senior Member |
|
|
А я тут за эксперименты взялся:
- IBSql фетчит и помещает в memdataset 1'000'000 записей за 8-9 сек. Правда, это на простенькой таблице с ID и varchar(20)
- VirtualTreeString заполняется 1'000'000 записей из memdataset за 4 сек. Причем скроллируется этот миллион в гуе без каких-либо лагов и артефактов!
Щас ещё поэкспериментирую, можно ли в основном потоке загрузить, скажем, 1000 записей, а в доппотоке "догрузить" в дерево оставшиеся записи незаметно для юзера
FPC/Lazarus (trunk) | Win10 x64 Ultim/Debian 11 amd64/Darwin x86_64 Monterey | Firebird 3.0.10 x64 | IBX by TonyWhyman
https://zoltanleo.blogspot.com/
[Обновления: Fri, 27 January 2023 00:00] Известить модератора
|
|
|
Re: IBX: буферизация записей [сообщение #1490 является ответом на сообщение #1489] |
Fri, 27 January 2023 01:40 |
SD
Сообщений: 417 Зарегистрирован: August 2022
|
Senior Member |
|
|
Док писал(а) Thu, 26 January 2023 21:56- VirtualTreeString заполняется 1'000'000 записей из memdataset за 4 сек. Причем скроллируется этот миллион в гуе без каких-либо лагов и артефактов!
"А ми же вас предупреждаль..." Если выкинуть из картины memdataset - будет ещё быстрее.
Фоновая загрузка тоже сильная вещь, но надо делать аккуратно: в потоке получать данные, а в контрол их добавлять просить основной поток через PostMessage, поскольку гуй в дельфи сделан так, что грабли лежат где не ждёшь.
[Обновления: Fri, 27 January 2023 01:41] Известить модератора
|
|
|
|
|
|
Re: IBX: буферизация записей [сообщение #1497 является ответом на сообщение #1496] |
Fri, 27 January 2023 23:38 |
|
Старый Плюшев
Сообщений: 95 Зарегистрирован: August 2022 Географическое положение: Ленинград
|
Member |
|
|
МП писал(а) Fri, 27 January 2023 17:32SDВторой пункт вредный. Понижает реактивность интерфейса. Пользователи не любят когда кнопки лагают. рюмка водки crSQLWait на экране снимает симптомы обсессивно-компульсивной тревожности.
В смысле - Такого ещё не было! Русский холод! 150 грамм непревзойдённого насыщенного вкуса в одном запотевшем стаканчике? Это снимет любой симптом. Но дороговасто будет.
По делу - мне кажется что в общем случае всё это ловля блох. Нет, есть какие-то вырожденные случаи, но реально заметные тормоза не здесь живут.
[Обновления: Fri, 27 January 2023 23:41] Известить модератора
|
|
|
Re: IBX: буферизация записей [сообщение #1498 является ответом на сообщение #1491] |
Sat, 28 January 2023 13:44 |
tarakan
Сообщений: 2 Зарегистрирован: January 2023
|
Junior Member |
|
|
Цитата:1. Зачем тут датасет??? Хочется помедленнее и пообъемнее?
2. Зачем заранее загружать поля записей, которые не видны на экране? Загружай, когда контрол об этом попросит, и кэшируй значения.
Подскажите, как быть в такой ситуации :
Есть 2 таблицы
1. "Группы товаров"
2. "Товары"
Связанные между собой по GROUPID
Как я понимаю нужно загрузить "Группы товаров", а товары к ним по мере обращения. НО... У каждого списка как правило должен быть поиск : edit, где по мере набора фильтруются записи. Получается при выполнении данного функционала(если этот VTV) будут грузиться сразу несколько десятков/сотен чилдов ROOTNODE. При не стабильном соединении с БД это может привести к большому "висяку". Как быть в данной ситуации?
[Обновления: Sat, 28 January 2023 13:44] Известить модератора
|
|
|
Re: IBX: буферизация записей [сообщение #1499 является ответом на сообщение #1498] |
Sat, 28 January 2023 17:18 |
Сообщений: 198 Зарегистрирован: September 2022
|
Senior Member |
|
|
tarakan писал(а) Sat, 28 January 2023 13:44Цитата:1. Зачем тут датасет??? Хочется помедленнее и пообъемнее?
2. Зачем заранее загружать поля записей, которые не видны на экране? Загружай, когда контрол об этом попросит, и кэшируй значения.
Подскажите, как быть в такой ситуации :
Есть 2 таблицы
1. "Группы товаров"
2. "Товары"
Связанные между собой по GROUPID
Как я понимаю нужно загрузить "Группы товаров", а товары к ним по мере обращения. НО... У каждого списка как правило должен быть поиск : edit, где по мере набора фильтруются записи. Получается при выполнении данного функционала(если этот VTV) будут грузиться сразу несколько десятков/сотен чилдов ROOTNODE. При не стабильном соединении с БД это может привести к большому "висяку". Как быть в данной ситуации?
Если нет стабильного соединения, то меняй архитектуру программного комплекса, визуальный интерфейс или набор требований.
Например, посмотри как сделано отображение и поиск в каком - нибудь мобильном приложении авито или озон. Там нет явного мастер - деталь отображения, и в то же время есть категорирование и куча фильтров, и никто не грузит все на клиента. И нет не то что стабильного - вообще нет постоянного коннекта.
|
|
|
Re: IBX: буферизация записей [сообщение #1500 является ответом на сообщение #1490] |
Sat, 28 January 2023 18:45 |
|
Док
Сообщений: 101 Зарегистрирован: June 2022
|
Senior Member |
|
|
SD писал(а) Fri, 27 January 2023 01:40Фоновая загрузка тоже сильная вещь, но надо делать аккуратно: в потоке получать данные, а в контрол их добавлять просить основной поток через PostMessage, поскольку гуй в дельфи сделан так, что грабли лежат где не ждёшь.
гуй подлагивает, даже если подгружать в потоке по 1000 записей.
Я хочу попробовать поместить два взаимоскрывающих друг друга дерева: первое загружается первыми 1000 записями, второе - невидимое - заполнять в потоке и показать, когда все будет закончено (скрыв при этом первое). Посмотрю, чо будет в визуалке
FPC/Lazarus (trunk) | Win10 x64 Ultim/Debian 11 amd64/Darwin x86_64 Monterey | Firebird 3.0.10 x64 | IBX by TonyWhyman
https://zoltanleo.blogspot.com/
[Обновления: Sat, 28 January 2023 19:19] Известить модератора
|
|
|
Re: IBX: буферизация записей [сообщение #1501 является ответом на сообщение #1491] |
Sat, 28 January 2023 18:56 |
|
Док
Сообщений: 101 Зарегистрирован: June 2022
|
Senior Member |
|
|
МорскойДесант писал(а) Fri, 27 January 2023 06:341. Зачем тут датасет??? Хочется помедленнее и пообъемнее?
2. Зачем заранее загружать поля записей, которые не видны на экране? Загружай, когда контрол об этом попросит, и кэшируй значения.
1. искать записи по меморидатасету проще, чем писать функции поиска по VTV - посмотрю
2. тогда при скроле придется отслеживать, достигли ли мы последний(нижний) узел дерева, и фетчить записи, начиная с определенного ID. А если ранее загруженные записи были изменены, то в целом данные в дереве уже будут не актуальны. Проще обновлять мемдатасет и грузить актуальные записи. К тому же, для экспериментов я беру самые экстремальные условия: без фильтрации, огромное кол-во записей - в реальности вряд ли такое встретится
FPC/Lazarus (trunk) | Win10 x64 Ultim/Debian 11 amd64/Darwin x86_64 Monterey | Firebird 3.0.10 x64 | IBX by TonyWhyman
https://zoltanleo.blogspot.com/
|
|
|
|
Re: IBX: буферизация записей [сообщение #1503 является ответом на сообщение #1500] |
Sat, 28 January 2023 19:20 |
|
Док
Сообщений: 101 Зарегистрирован: June 2022
|
Senior Member |
|
|
SD писал(а) Fri, 27 January 2023 01:40Фоновая загрузка тоже сильная вещь, но надо делать аккуратно: в потоке получать данные, а в контрол их добавлять просить основной поток через PostMessage, поскольку гуй в дельфи сделан так, что грабли лежат где не ждёшь.
гуй подлагивает, даже если подгружать в потоке оставшиеся 999000 по 1000 записей.
Я хочу попробовать поместить два взаимоскрывающих друг друга дерева: первое загружается первыми 1000 записями, второе - невидимое - заполнять в потоке и показать, когда все будет закончено (скрыв при этом первое). Посмотрю, чо будет в визуалке
FPC/Lazarus (trunk) | Win10 x64 Ultim/Debian 11 amd64/Darwin x86_64 Monterey | Firebird 3.0.10 x64 | IBX by TonyWhyman
https://zoltanleo.blogspot.com/
[Обновления: Sun, 29 January 2023 00:52] Известить модератора
|
|
|
|
Re: IBX: буферизация записей [сообщение #1505 является ответом на сообщение #1501] |
Sun, 29 January 2023 03:33 |
Сообщений: 198 Зарегистрирован: September 2022
|
Senior Member |
|
|
Док писал(а) Sat, 28 January 2023 18:56МорскойДесант писал(а) Fri, 27 January 2023 06:34
2. Зачем заранее загружать поля записей, которые не видны на экране? Загружай, когда контрол об этом попросит, и кэшируй значения.
2. тогда при скроле придется отслеживать, достигли ли мы последний(нижний) узел дерева, и фетчить записи, начиная с определенного ID. А если ранее загруженные записи были изменены, то в целом данные в дереве уже будут не актуальны. Проще обновлять мемдатасет и грузить актуальные записи. К тому же, для экспериментов я беру самые экстремальные условия: без фильтрации, огромное кол-во записей - в реальности вряд ли такое встретится
Возможно, я ошибаюсь, то мне кажется, что ты просто не знаешь, как работает VTV.
Смотри: вот сообщаешь ему, что у тебя в выборке 1 млн записей. Этого достаточно, чтобы дерево правильно отображало скролл.
Дерево хочет показать тебе данные и сразу выдает коллбэк: "А покажи мне данные узлов номер 1, 2, 3 ... <номер последнего видимого узла>". А если ты нажал <End> (переход в конец) , то дерево сразу попросит показать последние записи из твоего миллиона, не запрашивая промежуточные.
Тебе, как программисту, нужно в реализации упомянутой коллбэк функции всего лишь преобразовать номер узла в id записи и обратиться за ними в кэш. А кэш, если в нем нет данных по запрошенному id, должен выполнить физическую выборку нужных данных (и запомнить - он же кэш).
Насчет актуальности данных. Если тебе нужны данные, актуальные на момент запроса - то формируй отчет и смотри на него, не морочь себе голову.
А если тебе нужно и редактирование просматриваемых данных, то тебе нужны данные, актуальные на момент просмотра - и тут предложенная схема очень даже. При изменении/удалении данных (в т.ч. другими юзерами) ты видишь результаты сразу: подписываешься на события сервера "удаление/обновление", и получении сигнала просто сбрасываешь кэш (сделай его небольшим, на два-три экрана - перечитается мгновенно). При добавлении - энейблишь кнопку "Данные были добавлены, посмотреть" - и при нажатии запускаешь процесс инициализации дерева с нуля, с позиционированием кадра, соответствующем твоему видению прекрасного. А если данные добавил/изменил именно ты, то просто добавляешь/удаляешь соотв. узел и видишь результат сразу.
У меня по этой схеме в нескольких конторах приложение работает, с сотнями юзеров - и смотрят и редактируют, а в качестве сервера порой такие убогие машинки работаю, и все нормально ещё со времен беты FB 2.0 (на днях на fb 3.0 перетянул).
[Обновления: Sun, 29 January 2023 03:41] Известить модератора
|
|
|
|
Переход к форуму:
Текущее время: Sun Dec 22 14:54:56 GMT+3 2024
Общее время, затраченное на создание страницы: 0.02500 секунд
|