将100万个小记录插入可扩展存储引擎(JetBlue) - 很快

时间:2010-12-12 18:01:35

标签: 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.

谢谢!

2 个答案:

答案 0 :(得分:5)

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

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

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

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

答案 1 :(得分:1)

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