DBGrid с возможностью упреждающего чтения с использованием ADO

Я работаю с ADO, подключаясь к SQL Server 2005.

Мой TADODataSet выбирает 1 миллион записей. используя TDBGrid и устанавливая TADODataSet.CursorLocation в clUseServer работает. но TDBGrid задыхается!

Как я могу выбрать 1 миллион записей, избежать подкачки и по-прежнему иметь возможность отображать записи в сетке, не извлекая ВСЕ записи на сторону клиента, позволяя сетке читать вперед при прокрутке вверх и вниз?

Менеджер предприятия SQL может выполнить запрос и выбрать 1 миллион записей асинхронно без каких-либо проблем (также MS-ACCESS).


person kobik    schedule 17.12.2011    source источник
comment
Вы пытались поместить ClientDataset между ними? В конечном итоге он по-прежнему будет извлекать все записи, но после загрузки лота он может просматриваться быстрее.   -  person GolezTrol    schedule 17.12.2011
comment
Я не хочу получать 1 миллион записей на стороне клиента. ClientDataset сделает именно это.   -  person kobik    schedule 17.12.2011
comment
Кажется, TClientDataSet.PacketRecords звучит многообещающе для вас. Я никогда не пробовал это и не могу проверить сейчас, но кажется, что если вы установите его на видимое количество строк сетки БД и получите данные в TClientDataSet.BeforeGetRecords, то вы получите то, что хотите. Другое дело, что вам придется самостоятельно обрабатывать прокрутку (поскольку сетка БД не будет знать общее количество строк), и вам придется извлекать данные вручную.   -  person TLama    schedule 18.12.2011
comment
@TLama: при использовании инкрементной выборки с TDBGrid не нужно извлекать данные вручную. Сетка не знает общее количество записей (это происходит с любым набором данных, который не извлекает весь набор данных сразу), а затем просто показывает полосу прокрутки посередине — когда сетка достигает последней извлеченной записи, набор данных будет автоматически извлекать другой набор пакетов, если не указано иное, и сетка будет продолжать работать, т. е. полоса прокрутки будет сброшена, чтобы сообщить пользователю, что набор данных не является ни EOF, ни BOF.   -  person    schedule 18.12.2011
comment
@Idsandon, как я уже сказал, я никогда не пробовал этого и сейчас не могу. Итак, как CursorType и CacheSize, о которых вы упомянули, влияют на выборку? PacketRecords тоже влияет? Я не говорю о теории, зачем извлекать так много данных, скажем, мне нужно извлекать их постепенно по какой-то причине. Я хотел бы знать, что я должен настроить для этой автоматической добавочной выборки. Какой-то пример кода был бы лучшим;)   -  person TLama    schedule 18.12.2011


Ответы (3)


TGrid — не ваша проблема. Ваша проблема в том, что TADODataset пытается загрузить все записи. Если вам нужно выполнить запрос, который возвращает так много записей, вы должны установить ExecuteOptions, попробуйте eoAsyncExecute и eoAsyncFetch. Также может помочь установка CacheSize.

person crefird    schedule 18.12.2011

  • Зачем вам нужно извлекать 1 миллион записей в сетку? Ни один человек не может просмотреть столько записей. Обычно гораздо лучше уменьшить количество записей перед их загрузкой в ​​пользовательский интерфейс.
  • Если у вас есть веская причина отображать так много записей в сетке, вам нужен набор данных, который 1) не загружает весь набор записей при открытии 2) не кэшировать предыдущую запись, иначе может закончиться нехватка памяти (особенно в 32-битной Windows) задолго до достижения конца набора записей, если размер записи недостаточно мал. Чтобы получить такой результат за пределами CursorLocation, вы должны правильно установить CursorType и CacheSize.
  • Вы можете использовать TClientDataset для реализации добавочной выборки, задав для набора данных ADO CursorType значение ForwardOnly, а CacheSize — подходящее значение. Поскольку TClientDataset кэширует прочитанные записи, вы хотите, чтобы исходный набор данных не загружал их все. Стандартной сетке БД нужен двунаправленный курсор, поэтому он не будет работать с однонаправленным. При таком количестве записей кэш клиентского набора данных в любом случае может исчерпать память. Я бы посоветовал использовать модуль Midas Speed ​​Fix, если вы используете версию Delphi. до 2010 года.
  • Чтобы избежать ошибок «недостаточно памяти», вам может потребоваться реализовать разбиение на страницы. В любом случае, проверьте, может ли вам помочь поведение другого CursorType.
person Community    schedule 17.12.2011

Вы можете попробовать AnyDAC и TADTable. Режим Окно оперативных данных решает ваши и подобные проблемы. Преимущества:

  • минимизирует использование памяти и позволяет работать с большими объемами данных, аналогично однонаправленному набору данных;
  • обеспечивает двунаправленную навигацию, в отличие от однонаправленного набора данных;
  • дает всегда свежие данные, уменьшая необходимость обновления набора данных;
  • не задерживает получение всех записей набора результатов, необходимых для выполнения сортировки, расположения записи, перехода к последней записи и т. д.
person da-soft    schedule 18.12.2011