【发布时间】:2017-08-31 07:06:58
【问题描述】:
我有一个 Delphi 应用程序,它通过 FireDac 组件 TFDTable 将大约 200,000 条记录(约 1GB)插入 SQLite 数据库。当它插入时,我可以看到应用程序内存在增加,直到出现“内存不足错误”。我猜它与缓存和分页有关,但我找不到任何可以修复它的东西,除了每 1000 条记录左右关闭和重新打开数据库。想法?
已编辑... 对不起,措辞薄弱的问题...... 代码很简单,所以我没有包含它,但看起来基本上是这样的:
procedure DoIt;
begin
myDB.Insert;
myDBField1.AsString := StringOfChar('-',1000);
myDB.Post;
end;
现在,我预计内存可能会增加,因为字符串可能会复制到数据库缓存中。如果我使用 GetMemoryManagerState() 查看分配,我实际上可以看到这一点。我希望在某个时候,缓存中的内存会在数据写入磁盘时被刷新。然而,似乎并非如此。它会一直运行,直到我收到“内存不足”错误。
除了在连接中选择 sqlite 并向表中添加字段之外,通常大多数对象属性都设置为默认状态。
我知道这里没什么可做的。但我也不认为这会失败,我希望有人可能遇到过类似的问题。
【问题讨论】:
-
您如何发布一些重现该问题的代码?此外,您的 Delphi/FireDAC 版本可能很重要。
-
我们无法调试故事。请参阅:minimal reproducible example。如果不是,至少向我们展示一些相关代码。
-
数据感知组件会带来相当多的开销,这可能会妨碍真正大型但直接的工作。这就是为什么我在 sqlite DLL 周围创建了一个“干净”的包装器:github.com/stijnsanders/TSQLite
-
有一个底层数据存储,如果您不将数据提交到 DBMS 中,该存储自然会缓存它们并增长。在没有看到您的代码的情况下很难在这里提出建议,但至少考虑使用 Array DML technique 批量执行。
-
您需要客户端的数据吗?我没有使用 FireDAC 的经验,但是您在客户端将数据插入数据集中,我发现它在那里占用内存是很自然的。您有一个长度至少为 1000 的字符串字段,乘以 200000 条记录。如果您不需要客户端上的这些数据,您可以查看executing commands in FireDAC。