2010-12-12 42 views
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。

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

就交易而言,我做了一些實驗,並且遇到了錯誤,如果我在一次交易中放置了太多數據,就會出現錯誤。我想更好地理解那裏發生了什麼 - 我是否有一個bug,或者是一個交易的上限,如果上限,我可以放大上限?我只是在研究這個問題,因爲我猜測一個事務讓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. 

的感謝!

回答

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),因此無法看到其他會話所做的修改,這些修改在事務開始後未提交或提交。這與讀取提交不同,您可以在另一個會話提交後看到更改。你可能需要考慮如何分配工作來處理這個問題。

+0

非常感謝! – stuck 2010-12-14 21:49:01

+0

這裏是一個鏈接到一個文檔Laurion張貼在MSDN http://blogs.msdn.com/b/laurionb/archive/2008/11/07/some-basic-esent-performance-measurements.aspx – stuck 2010-12-21 02:04:47

+0

我不是獲得我希望看到的perf。我可以在一臺不錯的機器上(大約7200秒的SATA磁盤的i7)在約4.3秒內添加約10,000條非常小的記錄。只有當一個唯一的,非空字符串被添加到數據庫時,纔會出現問題。我看到CPU負載很低,並且在使用procmon進行監視時很少出現很小的寫入。考慮到記錄的小尺寸,這對我來說似乎沒有意義?我打電話給JetCommitTransaction(JET_bitCommitLazyFlush)。給定一切(延遲刷新+大maxVerPage值+低CPU負載+在procmon中測量的小IO)。我能做什麼?假設磁盤運動是可能的? – stuck 2011-06-07 02:15:33

1

確保您按順序插入。什麼是羣集(主)密鑰?它是一個人造汽車公司嗎?如果是這樣,那麼你按順序插入。你有多少個二級指標?理想情況下,您不需要任何插件,例如單獨的聚集插入將按索引順序。當按照索引順序插入時,JetUpdate僅附加到索引的末尾。這是比插入索引的中間更快。希望這會有所幫助,伊恩。