Delphi: ClientDataSet не работает с большими таблицами в Oracle

У нас есть TDBGrid, подключенный к TClientDataSet через TDataSetProvider в Delphi 7 с базой данных Oracle.

Показывать содержимое небольших таблиц нормально, но программа зависает, когда вы пытаетесь открыть таблицу с большим количеством строк (например, 2 миллиона строк), потому что TClientDataSet пытается загрузить всю таблицу в память.

Я попытался установить "FetchOnDemand" в True для нашего TClientDataSet и "poFetchDetailsOnDemand" в True в параметрах для TDataSetProvider, но это не помогло решить проблему. Какие-нибудь идеи?

Обновление:

Мое решение:

TClientDataSet.FetchOnDemand = T
TDataSetProvider.Options.poFetchDetailsOnDemand = T
TClientDataSet.PacketRecords = 500

Мне удалось решить проблему, установив свойство «PacketRecords» для TCustomClientDataSet. Это свойство указывает количество или тип записей в одном пакете данных. PacketRecords автоматически устанавливается на -1, что означает, что один пакет должен содержать все записи в наборе данных, но я изменил его на 500 строк.


person Andrey Prokhorov    schedule 06.02.2014    source источник
comment
Я думаю, этот пост могу помочь тебе.   -  person Iqbal    schedule 06.02.2014


Ответы (1)


При работе с СУБД, особенно с большими наборами данных, пытаться получить доступ ко всей таблице - это именно то, чего вам не следует делать. Это типичная ошибка новичков или заимствование старых файловых движков небольших баз данных. При работе с СУБД вы должны загружать только те строки, которые вас интересуют, отображать / изменять / обновлять / вставлять и отправлять обратно изменения в базу данных. Это означает, что SELECT с правильным предложением WHERE, а также ORDER BY - помните, что порядок строк никогда не гарантируется, когда вы запускаете SELECT без OREDER BY, механизм базы данных может извлекать строки в том порядке, который он считает подходящим для данного запроса. Если вам нужно выполнить массовые изменения, вам нужно сделать их в SQL и обработать их на сервере, а не загружать всю таблицу на стороне клиента, изменять ее и посылать изменения построчно в базу данных. Загрузка больших наборов данных на стороне клиента может быть неудачной по нескольким причинам: нехватка памяти (особенно 32-битных приложений), фрагментация памяти и т.д. сканирование, возможно, также очистка кеша базы данных и т. д. Таким образом, наборы клиентских данных не предназначены для обработки миллионов миллиардов строк. Они предназначены для кэширования строк, которые вам нужны на стороне клиента, а затем для применения изменений к удаленным данным. Вам необходимо изменить логику вашего приложения.

person Mad Hatter    schedule 07.02.2014
comment
Я не хочу загружать всю таблицу с 2 миллионами строк в памяти; Delphi пытается это сделать, если вы не установите правильные свойства в компонентах TClientDataSet и TDataSetProvider. - person Andrey Prokhorov; 08.02.2014
comment
@Andrey: да, вы не хотите, но вы делаете это :) Если вы вводите SELECT * FROM TABLE в таблице 2M строк, вы пытаетесь это сделать. Во-первых, ядро ​​базы данных думает, что вам нужны все 2M строк, и работает, чтобы получить их и отправить вам. Затем вы можете попытаться получить их по частям (но помните, что вы сказали движку БД, что вы уже хотите их все), но чем больше вы извлекаете, тем больше они заполняют вашу память. Если вы не получите их все, сервер выполнил некоторую бесполезную работу, используя потраченные впустую ресурсы. Вы всегда должны сообщать механизму БД, какие именно строки и в каком порядке вам нужны. - person Mad Hatter; 10.02.2014
comment
@Andrey: пока вы единственный пользователь базы данных с 2M строками, все может работать независимо от того, что вы делаете. Но когда у вас больше пользователей, каждая строка, которую вы извлекаете (с помощью SELECT, а не вашего клиента), должна активировать какие-то блокировки для реализации транзакций - для каждого пользователя. Их необходимо получить с диска и поместить в кеш и т. Д. и т. д. - все это общие ресурсы на сервере БД. Чем больше ресурсов использует каждый пользователь, тем меньше пользователей может поддерживать механизм БД на данном оборудовании. Хорошо написанное приложение БД использует меньше ресурсов, чтобы лучше масштабироваться. - person Mad Hatter; 10.02.2014