【发布时间】:2012-12-19 16:12:08
【问题描述】:
我在一个基于 c# 和 Fluent NHibernate 构建的项目中有各种大数据修改操作。 数据库是 sqlite(在磁盘上而不是在内存中,因为我对性能感兴趣)
我想检查这些性能,所以我创建了一些测试来输入大量数据并让流程完成它们的工作。其中两个过程的结果让我很困惑。
第一个是一个相当简单的例子,它获取 XML 文件中提供的数据,进行一些简单的处理并导入它。 XML 包含大约 172,000 行,运行该过程总共需要大约 60 秒,而实际插入大约需要 40 秒。
在接下来的过程中,我对同一组数据进行了一些处理。所以我有一个数据库,一张表中有大约 172,000 行。然后该过程处理这些数据,进行一些更繁重的处理并生成一大堆数据库更新(插入和更新到同一个表)。 总的来说,这会导致插入大约 50,000 行并更新 80,000 行。 在这种情况下,处理大约需要 30 秒,这很好,但是将更改保存到数据库需要 30 多分钟!它在完成之前崩溃并出现 sqlite 'disk or i/o error'
所以问题是:为什么第二个过程中的插入/更新要慢得多?他们使用相同的连接处理同一个数据库的同一张表。在这两种情况下,都使用 IStatelessSession 并且 ado.batch_size 设置为 1000。
在这两种情况下,代码看起来都像这样进行更新:
BulkDataInsert((IStatelessSession session) =>
{
foreach (Transaction t in transToInsert) { session.Insert(t); }
foreach (Transaction t in transToUpdate) { session.Update(t); }
});
(虽然第一个进程没有 'transToUpdate' 行,因为它只是插入 - 删除更新行并仅执行插入仍然需要将近 10 分钟。) transTo* 变量是列表,其中包含要更新/插入的对象。
BulkDataInsert 创建会话并处理数据库事务。
【问题讨论】:
标签: c# nhibernate