我有一个拥有300万条记录的Firebird数据库。我的FetchOptions
是禁用了RowsetSize := 1000
的FetchAll
。我在本地主机上工作。
我没有问题可以逐页浏览,但是当我单击DBNavigator
中的“ 转到最后一条记录”按钮时,会引发“ 内存不足”异常。
如果将UniDirectional
属性设置为True
,则没有问题。但是,移至最后一条记录会使应用程序冻结30-40秒。
问题和解决方案是什么?
问题是您的方法确实消耗了所有可用的内存,并且由于出现“内存不足”错误而被正确通知。所有记录均从服务器获取并保存在内存中。操作系统无法为您的应用分配更多资源。
该怎么办?只是避免加载数百万条记录。无论如何,您的用户将无法遍历/浏览/检查该庞大数据集中的每条记录。
要考虑的选项:
当FireDAC查询设置为单向时,它将在访问记录后从内存中删除记录。这样可以确保不会发生内存溢出。
移至最后一条记录的时间延迟是由于访问了每个中间记录,这显然需要一些时间。
解决方案是使用TFDTable数据集而不是默认的一个TFDQuery。 TFDTable数据集支持实时数据窗口模式。在这种模式下,数据集是双向的,因此可以与可视组件(例如TDBGrid)一起使用。与TFDQuery相比,差异是旧记录被丢弃。每次即时数据集仅在内存中保留2 * FetchOptions.RowsetSize记录(默认值2 * 50 = 100条记录),即进入表数据的窗口。当应用程序浏览表数据时,FireDAC会自动滚动或将“实时数据”窗口定位到所需位置。这提供了以下好处:
在LDW模式下,将Filter属性值原样替换为WHERE短语。根据设计,LDW模式始终将ORDER BY短语应用于SELECT命令。正确的LDW工作的关键要求是:
尽管FireDAC在LDW模式下最大程度地减少了生成和执行的SQL命令的数量,但它仍然比TFDQuery产生更大的数据库负载。因此,应用程序开发人员应谨慎选择何时使用TFDTable和LDW模式。
设置LDW模式
当满足以下所有条件时,将使用LDW模式:
否则,使用标准模式。
更多信息可以在Embarcadero文档中找到:http://docwiki.embarcadero.com/RADStudio/Berlin/en/Browsing_Tables_(FireDAC)#Live_Data_Window_Mode