4

我希望 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/和漂亮的磁盘?我要打开数据库两次然后从那里去吗?我不太确定在线程安全和事务方面会发生什么。如果我有两个数据库句柄,每个句柄都在一个事务中,那么在提交之前,第二个句柄是否可以立即写入,还是我需要先提交?

任何提示表示赞赏

    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.

谢谢!

4

2 回答 2

5

对于单线程性能,最重要的是要查看您的事务模型。

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

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

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

于 2010-12-14T15:29:32.720 回答
1

确保您“按顺序”插入。什么是集群(主)键?它是一个人工汽车公司吗?如果是这样,那么您将按顺序插入。你有多少个二级索引?理想情况下,您将没有任何插入,以便所有插入(例如单独的聚集插入)都按索引顺序排列。当您按索引顺序插入时,JetUpdate 仅附加到索引的末尾。这比插入索引中间要快得多希望这会有所帮助,伊恩。

于 2013-02-25T14:48:21.350 回答