我们有一个TDBGrid通过Delphi 7中的TDataSetProvider与Oracle数据库连接到TClientDataSet。
可以显示小表的内容,但是当您尝试打开包含许多行的表(对于前200万行)时,程序会挂起,因为TClientDataSet会尝试将整个表加载到内存中。
我尝试将TClientDataSet的“FetchOnDemand”设置为True,并在TDataSetProvider的Options中将“poFetchDetailsOnDemand”设置为True,但它无法解决问题。任何想法?
更新
我的解决方案是:
TClientDataSet.FetchOnDemand = T
TDataSetProvider.Options.poFetchDetailsOnDemand = T
TClientDataSet.PacketRecords = 500
我成功地通过为TCustomClientDataSet设置“PacketRecords”属性来解决问题。此属性指示单个数据包中的记录数量或类型。 PacketRecords自动设置为-1,这意味着单个数据包应包含数据集中的所有记录,但我将其更改为500行。
答案 0 :(得分:1)
使用RDBMS时,尤其是使用大型数据集时,尝试访问整个表正是您不应该做的。这是一个典型的新手错误,或借用旧的基于文件的小型数据库引擎。 使用RDBMS时,您应该只加载您感兴趣的行,显示/修改/更新/插入,并将更改发送回数据库。这意味着SELECT具有正确的WHERE子句以及ORDER BY - 当您发出没有OREDER BY的SELECT时,永远不会确保行排序,数据库引擎可以按照它认为适合给定查询的顺序自由检索行。 如果必须执行批量更改,则需要在SQL中执行它们并在服务器上处理它们,而不是加载整个表客户端,修改它,并将更改逐行发送到数据库。 加载大型数据集客户端可能会出于多种原因,内存不足(尤其是32位应用程序),内存碎片等等,您可能会使用不需要的数据充斥网络,强制数据库执行完整扫描,也可能是数据库缓存,等等。 因此,客户端数据集不是为处理数百亿行而设计的。它们旨在缓存客户端所需的行,然后将更改应用于远程数据。您需要更改应用程序逻辑。