2017-01-28 70 views
1

我正在使用java中的多線程讀取vertica數據庫中的數據。 我有大約20萬條記錄,我打開5個不同的線程有這樣的選擇查詢....通過java中的多線程從數據庫中讀取

start = threadnum; 

while (start*20000<=totalRecords){ 

    select * from tableName order by colname limit 20000 offset start*20000. 

    start +=5; 

} 

上述查詢分配20K重複的記錄從數據庫到每個線程讀取。 例如第一個線程會先讀取20k個記錄,然後從100 000個位置開始讀取20K個記錄等

但是我沒有得到性能改進。事實上,如果使用單個線程需要x秒來讀取2000萬條記錄,那麼每個線程從數據庫讀取需要幾乎x秒的時間。 x秒(x/5秒)不應該有所改善嗎?

任何人都可以指出哪裏出了問題?

+0

遵循這個邏輯,你只需要用''n''來增加線程數,以減少總處理時間''1/n''。 – Matt

+0

網絡不是多線程的。你可以使用盡可能多的線程,但一旦你使網絡飽和,就是這樣,沒有進一步的改進可能。 – EJP

回答

0

不,你不應該得到x/5秒。你沒有想到你在相同的時間內獲得了5倍的記錄數量這一事實。這是關於吞吐量,而不是時間。

2

除了你理解什麼情況可以通過多線程改善以及什麼情況可能沒有改善之外,沒有什麼問題了。

您的數據庫可能位於磁盤上;這是一個磁盤與一組磁頭一起移動,所以它就像是說它是一個單磁頭磁盤一樣。頭部需要時間從一個位置移動到另一個位置;這叫做尋找時間

當您從一個線程讀取順序數據時,頭部必須在軌道之間移動很少。

當你從多個線程讀取不同的順序數據流時,頭部必須移動很多才能從一個軌道跳到另一個很遠的軌道,然後返回到第一個軌道。這是很大的尋求開銷。

然後,當然你的硬盤通過一根電纜連接到你的主板上,所以所有的數據(在所有的搜索開銷之後)必須通過它才能被不同的線程處理。

結果當然是非常糟糕的表現。

帶回家的教訓是這樣的:在同一個設備

大規模的I/O永遠不能憑藉多線程得到改善。

用不同的術語來說:處理數據時的並行性決不會在所有數據來自單個連續源時提高性能。

如果您有5個不同的數據庫存儲在5個不同的磁盤上,那會更好。 (如果您還將這些磁盤連接到主板上的5個獨立IDE控制器,那麼效果會更好。)

0

我就不重複了邁克Nakis說,因爲它是真實的,很好的解釋:

I /從一個物理磁盤Ø無法通過多線程

改善盡管如此,我想添點什麼。從客戶端

select * from tableName order by colname limit 20000 offset start*20000. 

你可以處理,你可以通過使用多線程提高了查詢的結果:

當你執行一個查詢這樣。

但是從數據庫方面來說,您還沒有掌握查詢的處理過程,並且Vertica數據庫可能旨在通過根據機器可能性執行並行任務來執行您的查詢。

所以從客戶端你可以在一個,兩個或三個並行線程中拆分你的查詢的執行,最終它不應該改變很多事情,因爲專業數據庫被設計爲根據數量優化響應時間要求它接收和機器的可能性。