2014-02-06 19 views
0

我們有一個TDBGrid,它通過Delphi 7中的TDataSetProvider與Oracle數據庫連接到TClientDataSet。Delphi:客戶端數據集不適用於Oracle中的大表格

它可以很好地顯示小表的內容,但是當您嘗試打開一個有許多行的表(對於2百萬行)時程序掛起,因爲TClientDataSet嘗試在內存中加載整個表。

我嘗試在TDataSetProvider的選項中爲我們的TClientDataSet和「poFetchDetailsOnDemand」設置爲「FetchOnDemand」爲True,但它無助於解決問題。任何ides?

更新:

我的解決辦法是:

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

我成功通過設置TCustomClientDataSet了 「PacketRecords」 屬性來解決這個問題。該屬性表示單個數據包中記錄的數量或類型。 PacketRecords自動設置爲-1,這意味着一個數據包應包含數據集中的所有記錄,但我將其更改爲500行。

+0

我認爲[這篇文章](http://stackoverflow.com/questions/343553/how-to-prevent-delphi-ado-from-loading-the-entire-table-into-memory)可以幫助ypu。 – Iqbal

回答

1

使用RDBMS時,特別是對於大數據集,嘗試訪問整個表正是您不應該這樣做的。這是一個典型的新手錯誤,或從舊的基於文件的小型數據庫引擎中借用。 使用RDBMS時,應該只加載您感興趣的行,顯示/修改/更新/插入,並將更改發送回數據庫。這意味着一個帶有適當的WHERE子句的SELECT以及一個ORDER BY - 當你發出沒有OREDER BY的SELECT時,記得行的排序永遠不會得到保證,數據庫引擎可以按照它認爲適合給定查詢的順序自由地檢索行。 如果必須執行批量更改,則需要在SQL中執行這些更改,並在服務器上處理它們,不加載整個表客戶端,修改它,並逐行將更改發送到數據庫。 加載大型數據集客戶端可能由於多種原因,缺乏內存(尤其是32位應用程序),內存碎片等等,您將使用您不需要的數據氾濫網絡,迫使數據庫執行全面掃描,也許還會修改數據庫緩存,等等。因此,客戶端數據集不能用於處理數百萬億行。它們旨在緩存需要客戶端的行,然後將更改應用於遠程數據。您需要更改您的應用程序邏輯。

+0

+1過濾是關鍵。 –

+0

我不想在內存中加載200萬行的整個表格;如果你沒有在TClientDataSet和TDataSetProvider組件中設置正確的屬性,Delphi會嘗試這樣做。 –

+0

@Andrey:是的,你不需要,但是你在做:)如果你在2M行表上發出SELECT * FROM TABLE,你試圖去做。首先,數據庫引擎認爲你想要所有的2M行,並努力檢索併發送給你。然後你可以嘗試通過塊檢索它們(但是記住你已經告訴數據庫引擎你想要所有這些),但是檢索得越多,它們就越充滿你的記憶。如果你沒有全部檢索它們,服務器使用浪費的資源做了一些無用的工作。您應該始終告訴數據庫引擎您想要的行數以及順序。 –

相關問題