database - 将一百万条小记录插入可扩展存储引擎 (JetBlue) - 快速

标签 database jet extensible-storage-engine

我希望 Laurion Burchall 能读到这篇文章:-)

我需要尽快插入一百万条小记录。

现在我正处于一个非常紧凑的循环中,对于每条记录,我都

a) start a transaction  (JetBeginTransaction)
b) prepare an update (JetPrepareUpdate)
c) add the row (JetSetColumns)
d) commit the transaction (JetCommitTransaction)

现在,在此过程中,我在一个处理器上处于紧密循环状态。目标机器有多个 CPU、大容量磁盘和大量空闲 RAM。

我想知道如何获得更好的性能。

就交易而言,我做了一些实验,如果我在一个交易中放入太多数据,就会出现错误。我想更好地了解那里发生了什么——我有错误吗,或者交易的规模是否有上限,如果有上限我可以扩大上限吗?我只是在调查这个,因为我猜测事务使 ESE 能够在 RAM 中进行更多缓存,从而最大限度地减少磁盘刷新? - 这只是一个猜测?

一般来说,我如何使用多个处理器/大量 RAM/和不错的磁盘?我应该打开数据库两次然后从那里开始吗?我不太确定在线程安全和事务方面会发生什么。如果我有两个 DB 句柄,每个句柄都在一个事务中,那么在提交之前,对一个句柄的写入是否可以立即用于第二个句柄,还是我需要先提交?

感谢任何提示

    here are the constraints    

a) I've got a million records that need to be written into the DB as fast as possible
b) to fully generate the record for insertion there are two searches that need to occur within the same table (seeking keys)
c) This is a rebuild/regeneration of the DB - it either worked, or it didnt.  
   If it didnt there is no going back, a fresh rebuild/regeneration is
   needed.  I cannot restart mid process and without all the data none of 
   the data is valuable.  READ: having one big transaction is fine if it 
   improves perf.  I'd like ESE to cache, in ram, if that helps perf.

谢谢!

最佳答案

对于单线程性能来说,最重要的是你的事务模型。

如果您尝试在一个事务中放入更多数据但失败了,您可能遇到了 JET_errOutOfVersionStore。 Esent 必须跟踪事务中执行的所有操作的撤消信息(以启用回滚),并且该信息存储在版本存储中。版本存储的默认大小非常小。您可以使用 JET_paramMaxVerPages 系统参数来增加它。值 1024(64MB 的版本存储)将启用相当大的事务。我建议每笔交易进行 100-1000 次插入。

当您调用 JetCommitTransaction 时,Esent 会将日志刷新到磁盘,生成同步 I/O。为避免将 JET_bitCommitLazyFlush 传递给 JetCommitTransaction。你的交易仍然是原子的,但在崩溃的情况下不持久(如果你正常退出,一切都会好起来的)。看起来应该可以找到供您使用。

如果您按升序插入记录,那么您可以使用单线程应用程序。如果您可以更改您的实现以执行顺序插入,那么您应该——它们会快得多。对于随机插入,多线程可能很有用。要使用多线程,您只需创建新 session (JetBeginSession) 并让它们打开数据库 (JetOpenDatabase)。 Esent 使用快照隔离 (http://en.wikipedia.org/wiki/Snapshot_isolation),因此无法看到其他 session 所做的未提交或在您的事务开始后提交的修改。这与读取提交不同,在读取提交中您可以在另一个 session 提交后看到更改。您可能需要考虑如何分工来处理这个问题。

关于database - 将一百万条小记录插入可扩展存储引擎 (JetBlue) - 快速,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4423077/

相关文章:

mysql - 我试图找出增长最快的账户(就余额而言)

mysql - 在mysql数据库中获取多行

oledb - Jet OLEDB :Transaction Commit Mode and Jet OLEDB:User Commit Sync? 有什么区别

c - 如何使用C语言和esent.lib读取ESE表中的列名?

c++ - 如何使用cpp从ESE数据库中读取记录

sql - 定义数据库的表结构?

database - 如何使用进程内迁移运行器和内存 SQLite 数据库测试流畅的迁移

sql - ALTER TABLE 语句中的 DEFAULT 子句导致语法错误

SQL:如何显示仅30天的记录

database - 如何使可扩展存储引擎数据库收缩? - 数据库里面不应该有太多数据吗?