gpt4 book ai didi

sqlite - 在 SQLite、FireDac、Delphi 中插入记录时内存不足

转载 作者:行者123 更新时间:2023-12-02 07:56:47 24 4
gpt4 key购买 nike

我有一个 Delphi 应用程序,它通过 FireDac 组件 TFDTable 将大约 200,000 条记录(大约 1GB)插入到 SQLite 数据库中。当它插入时,我可以看到应用程序内存不断增加,直到出现“内存不足错误”。我猜这与缓存和分页有关,但除了每 1000 条记录左右关闭并重新打开数据库之外,我找不到任何解决该问题的方法。想法?

已编辑...抱歉问了这个措辞薄弱的问题......代码很简单,所以我没有包含它,但看起来基本上是这样的:

procedure DoIt;
begin
myDB.Insert;
myDBField1.AsString := StringOfChar('-',1000);
myDB.Post;
end;

现在,我预计内存可能会增加,因为字符串可能会复制到数据库缓存。如果我使用 GetMemoryManagerState() 查看分配,我实际上可以看到这一点。我预计在某个时刻,当数据写入磁盘时,缓存中的内存将被刷新。然而,似乎并非如此。它会一直持续下去,直到我收到“内存不足”错误为止。

一般来说,除了在连接中选择sqlite以及向表中添加字段之外,大多数对象属性都设置为默认状态。

我知道这里没有太多可做的。但我也不认为这会失败,我希望有人可能遇到过类似的问题。

最佳答案

TFDTable是一个查询对象的薄包装器,可以构建用于操作底层 DBMS 表的 SQL 命令。它有自己的存储( Table 对象),用于存储获取到客户端的数据以及您插入的元组。但所有这些都在内存中,没有底层文件缓存。

尽管在插入时可以清除内部存储,TFDTable不是插入如此大量数据的好对象。更好地使用查询对象,如 TFDQuery与名为 Array DML 的批处理命令执行技术相结合可以为您带来真正的性能提升,即使对于本地 DBMS 引擎也是如此。和TFDQuery不会缓存插入的元组。

当您使用索引参数绑定(bind)时,FireDAC 原生支持 SQLite 的这种技术,例如此代码应插入 200 次批量的 1000 个唯一元组:

const
BatchSize = 1000;
TotalSize = 200000;
var
Batch: Integer;
Index: Integer;
begin
FDQuery.SQL.Text := 'INSERT INTO MyTable VALUES (:p1, :p2)';
FDQuery.Params.BindMode := pbByNumber;
FDQuery.Params.ArraySize := BatchSize;

for Batch := 0 to TotalSize div BatchSize - 1 do
begin
for Index := 0 to BatchSize - 1 do
begin
FDQuery.Params[0].AsIntegers[Index] := (Batch * BatchSize) + Index;
FDQuery.Params[1].AsWideStrings[Index] := 'Some Unicode string value';
end;
FDQuery.Execute(BatchSize, 0);
end;
end;

关于sqlite - 在 SQLite、FireDac、Delphi 中插入记录时内存不足,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45975298/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com