Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Базы данных и репортинг > Число записей получаемых за одно обращение


Автор: UsamaBrainLaden 27.1.2009, 19:51
Работаю с сервером PostgreSQL версии 8.2.9, посредством ODBC + ADO (ADOConnection -> ADOQuery -> DataSetProvider -> ClientDataSet -> DataSource). Прочитал всё что можно было прочитать про Fetch'инг и свойство PacketRecord компонента ClientDataSet, уж очень не хочеться возиться с трёхзвенной архитектурой. Проблема в том, что когда я ставлю в свойстве PacketRecord = 10 (то есть грузи с сервера по 10 записей за одно обращение), то DBGrid делает полосу прокрутки как-будто в ней действительно 10 записей и по мере прокрутки она уменьшается (а число записей соответственно увеличивается) только все равно программа изначально тянет всю таблицу полностью с сервера,а не порциями по 10 записей. Хотелось бы просто сэкономить трафик и время ожидания пользователя (пока вся таблица стянеться). Как бы мне реализовать такое?

PS:
В ходе эксперимента я создавал на сервере таблицу с пол сотней тысяч записей и пытался работать с ней. Программа запускалась задумчиво, причем таблица качалась хоть и полностью, но быстро (сервак находится в локалькой сети 100 Мбит/сек),а сама инициализация программы длилась долго (я так понимаю из-за данных которым необходимо расположиться в памяти). Поэтому и хочу чтобы таблица тянулась не полностью а порциями по 10 (допустим) записей и по мере прокрутки DBGrid'а ClientDataSet подгружал бы необходимое число записей.

Автор: Rodman 27.1.2009, 20:02
а если в запросе ограничивать?

TOTAL или LIMIT???

Автор: Akella 28.1.2009, 14:28
Цитата(UsamaBrainLaden @  27.1.2009,  19:51 Найти цитируемый пост)
(ADOConnection -> ADOQuery -> DataSetProvider -> ClientDataSet -> DataSource). 

а почему не (ADOConnection -> ADOQuery -> DataSource)?

Добавлено через 3 минуты и 24 секунды
Цитата(UsamaBrainLaden @  27.1.2009,  19:51 Найти цитируемый пост)
аботаю с сервером PostgreSQL версии 8.2.9, посредством ODBC + ADO

Переходи на компоненты доступа ZeosDBO или на AnyDAC 1.х. И то, и то бесплатное. Но компоненты AnyDAC 2.x уже платные.
1. Будет быстрее.
2. Работа с базой "напрямую".
3. При распространении программы не нужно будет заставлять клиента ставить ODBC-драйвера
это так, по минимуму преимущества.

Автор: UsamaBrainLaden 30.1.2009, 03:35
Я давно уже хотел и перешёл седня, стянул Zeos 6.6.4. Но там та же песня ставлю 10 в PacketRecord Grid меняется соответственно, но таблица тянется все равно полностью. Насчет ограничения в запросе, то там в компонентах Query есть поле RecordsCount по моему, ставишь тупо 10 и он тебе 10 первых записей и выдает, а мне то нужно именно фетч (в справке по PostgreSQL есть раздел FETCH, что-то типа усекания).

Цитата(Akella @  28.1.2009,  14:28 Найти цитируемый пост)
а почему не (ADOConnection -> ADOQuery -> DataSource)?


просто этож не файл серверная программа, там смысл такой что когда очередной клиент присоединяется, то ему копируется вся или часть данных из базы и он работает локально. Тем более когда я переходил от разработки локальных БД к удалённым, то меня именно так учили (источники). Что-то даже помню про то что если делать при помощи этих трех компонент то в базу ниче записать не получиться. Там все сложнее, транзакции, сессии и метода Post мало, нужно ещё вызывать ApplyUpdates компонента ClientDataSet1.

Автор: Bose 30.1.2009, 16:42
UsamaBrainLaden, а какой grid используешь?
Просто, если Dataset подключен к гриду, то следует учесть DBGrid и сам может фетчить записи. Как минимум он фетчит столько записей сколько необходимо, чтобы заполнить видимую часть. А, некоторые "продвинутые гриды" в зависимости от настроек(обычно что-то типа UseLocalSort) могут фетчить вообще всё.

Добавлено через 1 минуту и 31 секунду
п.с. хотя с таким же успехом во всём может быть виноват и ClientDataset. Я его не использую, поэтому не знаю в деталях как он работает.

Автор: Akella 30.1.2009, 18:32
Цитата(Bose @  30.1.2009,  16:42 Найти цитируемый пост)
А, некоторые "продвинутые гриды" в зависимости от настроек(обычно что-то типа UseLocalSort) могут фетчить вообще всё.

Угу, например, cxGrid тянет на себя всё в режиме SyncMode = true.

Автор: UsamaBrainLaden 30.1.2009, 19:31
Цитата(Bose @  30.1.2009,  16:42 Найти цитируемый пост)
UsamaBrainLaden, а какой grid используешь?

Я использую обычный DBGrid

Цитата(Bose @  30.1.2009,  16:42 Найти цитируемый пост)
DBGrid и сам может фетчить записи

я так понимаю он будет фетчить чисто визуально, то есть таблица тянется полностью и размещается в ОП,а грид фетчит уже локальные данные и в итоге трафик тот же.

Цитата(Bose @  30.1.2009,  16:42 Найти цитируемый пост)
Я его не использую

А чем тогда? Connecton -> Query -> DataSource?
просто как тогда быть если два пользователя работают с одной записью, кто за этим будет следить?

Именно так разрабатывается клиент серверное приложение БД?
Просто зачем они нужны?
У фаронова эти компоненты приписаны к трёхзвенной архитектуре, самое интересное что моя задумка работает в следуешем случае:
Создается сервер приложений в Delphi (не буду вдаваться в подробности) и на него переносятся часть компонентов которые я использую, а именно: Connection, Query и DataSetProvider, потом этот сервер приложений запускается на отдельной машине и уже в дельяи создается сам клиент спомощью трех компонент, это ClientDataSet, DataSource и ещё одна байда которая с этим сервером коннектиться и все, при таком раскладе ставишь PacketRecord в 10 и он подгружает таблицу по 10 записей. вот!

Автор: Akella 30.1.2009, 20:29
Цитата(UsamaBrainLaden @  30.1.2009,  19:31 Найти цитируемый пост)
я так понимаю он будет фетчить чисто визуально, то есть таблица тянется полностью и размещается в ОП,а грид фетчит уже локальные данные и в итоге трафик тот же.

Нет, по идее грид управляет набором данных (Dataset`ом). Т.е. грид говорит набору данных, сколько записей нужно показать (вытянуть из базы данных).

Добавлено через 2 минуты и 23 секунды
Цитата(UsamaBrainLaden @  30.1.2009,  19:31 Найти цитируемый пост)
просто как тогда быть если два пользователя работают с одной записью, кто за этим будет следить?

Кто первый захватил на редактирование, тот и сможет работать с записью. Опять же, если нет взаимных блокировок, то тот, кто последний сохранил, тот и прав. Типа кто последний, тот и папа  smile.

Добавлено через 3 минуты и 20 секунд
Цитата(UsamaBrainLaden @  30.1.2009,  19:31 Найти цитируемый пост)
У фаронова эти компоненты приписаны к трёхзвенной архитектуре

Тебе нужна ИМЕННО трёхзвенка?

Автор: Bose 30.1.2009, 21:24
Цитата(UsamaBrainLaden @  30.1.2009,  18:31 Найти цитируемый пост)
просто как тогда быть если два пользователя работают с одной записью, кто за этим будет следить?


Вот, Akella ответил.
Цитата(Akella @  30.1.2009,  19:29 Найти цитируемый пост)
Кто первый захватил на редактирование, тот и сможет работать с записью. Опять же, если нет взаимных блокировок, то тот, кто последний сохранил, тот и прав. Типа кто последний, тот и папа 


В идеале хорошо, когда есть возможность блокировать запись при редактировании. На практике же чаще делаю как сказал Akella. Кто последний - тот и прав.

Автор: Akella 30.1.2009, 22:31
В любом случае нужно стараться реализовать приложение так, чтобы пишущая транзакция была как можно короче по времени, тогда и взаимных блокировок можно избежать.

Автор: UsamaBrainLaden 30.1.2009, 23:44
Мне в принципе все равно трех или двух звенная архитектура, я согласен работать и с тремя компонентами, только бы трафик резать, чтоб не все сразу тянул. У DBGrid я так понимаю нету подобных вещей, тогда с какой сеткой работать?

Добавлено через 14 минут и 10 секунд
Ну хорошо, перефразирую вопрос: неужели ни у кого не возникало таких проблем и все принимают это как должное, что таблицы тянуться целиком. Ведь это же нагрузка на сервер, на сеть, да и анлим далеко не у всех клиентов есть. Как подгружать какое-то определенное число записей и кешировать их для дальнейшего использования, Ладно черт с ним с трафиком, но ведь клиентская программа тогда грузиться будет долго если у него слабенький канал интернета, хотя сама она в реале уже будет давно загружена,а пользователь тупо ждет пока таблицы стянуться и так каждый раз.

Автор: Akella 31.1.2009, 00:33
Цитата(UsamaBrainLaden @  30.1.2009,  23:44 Найти цитируемый пост)
Ведь это же нагрузка на сервер, на сеть, да и анлим далеко не у всех клиентов есть. 

Тебе через интернет?  Может тогда лучше написать программу репликации?

Автор: Akella 31.1.2009, 00:59
Например, в ADOQuery есть CacheSize
из справки:
Цитата

Set CacheSize to control how many rows the ADO dataset’s provider keeps cached in its buffer and how many to retrieve at one time into local memory. Default value of CacheSize is 1 and the minimum allowed value is 1.


у ADODataSet есть MaxRecords
Цитата

Use MaxRecords to control the number of rows the provider for the ADO dataset component returns from the data source. Set MaxRecords to indicate the maximum number of rows. The default value for MaxRecords is 0 (zero), which places no limits on the result set.


У компонентов (FibPlus) pFIBDataSet есть свойство CacheModelOptions
Цитата

property CacheModelOptions:TCacheModelOptions, где

TCacheModelOptions = class(TPersistent)
property BufferChunks: Integer ;
property CacheModelKind: TCacheModelKind ;
property PlanForDescSQLs: string ;
end;

BufferChunks в данном случае заменяет существующее свойство BufferChunks у TpFIBDataSet. Тип TCacheModelKind может принимать значения cmkStandard, для использования стандартной работы локального буфера, и cmkLimitedBufferSize, для использования новой технологии ограниченного локального буфера. Размер буфера - это количество записей, указанных в свойстве BufferChunks.

Автор: UsamaBrainLaden 31.1.2009, 02:52
Ну яж перешёл на Zeos, теперь у меня ZQuery, а после него либо сразу DataSource либо DataSetProvider, ClientDataSet и DataSource.

Насчет MaxRows сразу могу сказать это одно и тоже что и LIMIT (выше уже рекомендовали) он тупо возвращает 10 первых записей.

Автор: Bose 31.1.2009, 06:45
Цитата(UsamaBrainLaden @  30.1.2009,  22:44 Найти цитируемый пост)
Мне в принципе все равно трех или двух звенная архитектура, я согласен работать и с тремя компонентами, только бы трафик резать, чтоб не все сразу тянул. У DBGrid я так понимаю нету подобных вещей, тогда с какой сеткой работать?

DbGrid просит у Dataseta только число видимых записей(~ 20).

Цитата(UsamaBrainLaden @  30.1.2009,  22:44 Найти цитируемый пост)
Ну хорошо, перефразирую вопрос: неужели ни у кого не возникало таких проблем и все принимают это как должное, что таблицы тянуться целиком.

Во-первых, таблицы тянутся целиком не всегда и во многом это зависит от используемых компонент для доступа к БД. Например, компоненты BDE - тянут все записи, компоненты IBX и FIBPlus(для работы с Firebird) тянут только необходимые видимые. FibPlus до кучи ещё умеет тянуть записи из середины, не делая fetch первым. Но это всё для Firebird-a. 

Каждый тип компонентов реализует эту часть по-своему. Как себя  ведут ZeosLib, Ado, dbExpress - я не знаю, я с ними не работал. 

Цитата(UsamaBrainLaden @  31.1.2009,  01:52 Найти цитируемый пост)
Ну яж перешёл на Zeos, теперь у меня ZQuery, а после него либо сразу DataSource либо DataSetProvider, ClientDataSet и DataSource.

Попробуй ради интереса подключить DataSource напрямую к ZQuery и посмотреть что будет. Ибо вполне может оказаться, что все записи из базы вытаскивают именно DataSetProvider и ClientDataSet.

Автор: UsamaBrainLaden 31.1.2009, 18:33
Цитата(Bose @  31.1.2009,  06:45 Найти цитируемый пост)
вполне может оказаться, что все записи из базы вытаскивают именно DataSetProvider и ClientDataSet.

Как раз таки нет, яж рассказывал про реализацию сервера приложений, то есть выношу Query и Porvider на сервер и всё нормуль, работает!  Не просто же так у ClientDataSet есть свойство PacketRecord. Я так порассуждал, что сам сервер БД не может отдавать порциями, он может только отдать все, либо ваще ниче, поэтому на отдельной машине ставиться сервер приложений с коннектом  к базе, Query и Provider'ом, а те в свою очередь такое делать могут и они отдают машине клиента, на которой стоят xxxConnection (у меня SocketConnection) ClientDataSet и DataSource. А с начала у меня все эти компоненты находились на одной форме, тоесть грубо говоря сервер приложений реализован был на клиентской стороне, так и получалось что Query тянул всю таблицу, а ClientDataSet из этой таблицы запрашивал 10 записей (тобиш у машины на которой находиться сам), и в результате клиентская машина все равно тянет всю базу.

Цитата(Bose @  31.1.2009,  06:45 Найти цитируемый пост)
Но это всё для Firebird-a. 

Вот именно, а я то с PostgreSQL работаю

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)