2012-05-25 33 views
0

我正在做一個搜索引擎的研究項目,並且我對for循環的性能有問題。我有以下問題:在巨大的列表或字典中的循環性能

for value in hash_array.keys(): 
     cell= db_conn.use_client().hql_query(db_conn.use_namespace(),'SELECT doc_text FROM SE_doc_text WHERE ROW=\"'+ 
          value+"\" SCAN_AND_FILTER_ROWS LIMIT 1").cells 
     list_result[value].append(cell[0].value) 

使用Hypertable的我想有最好的表現,但是當我使用它的hash_array.keys的20.000和30.000元()我有一個5-6分鐘的結果,所以這真的很慢。任何其他方式快速執行?或者我應該將我的計劃b用於整個搜索引擎。

性能查詢:

Elapsed time: 0.10 s 
Avg value size: 1428.00 bytes 
    Avg key size: 57.00 bytes 
    Throughput: 595190.38 bytes/s 
    Total cells: 1 
    Throughput: 400.80 cells/s 

測試硬件:

8gb 1600mhz 
1055t amd 

更多的事實:

Without SCAN_AND_FILTER_ROWS: 1.78163504601ms 
With SCAN_AND_FILTER_ROWS: 3.27163504601ms 
Only for loop: 0.0630ms 

通過該解決方案(從答案)我有以下幾點:

stringRow = ' AND '.join(["ROW = \""+value + "\"" for value in hash_array.keys()]) 
cell = db_conn.use_client().hql_query(db_conn.use_namespace(),stringBatch+stringRow).cells 

Results: 0.355320930481ms for 2097 documents 
      1.0214779377 for 3565 documents 

這很好,但它不是最好的解決方案。

+3

你肯定是的不是查詢開銷? – Anycorn

+6

而不是爲每個鍵做一個單獨的查詢,你可以批量發送多個鍵嗎?每個單獨查詢的開銷可能會在這裏佔據主導地位。 –

回答

2

我從來沒有用過Hypertable的,但僅僅讀documentation建議SCAN_AND_FILTER_ROWS條款可能是一個問題:

這對於你在一個非常大的數量的查詢 的情況下明確的優化行間隔(例如,10,000+)。代替 獨立提取每個行間隔,此選項將導致 系統執行全表掃描並過濾結果以查找所需的行 。請謹慎使用此選項,對於較少數量的行間隔,效率可能非常低。

如果您一次發送一批密鑰,本節可能會變得更合適。

閱讀更多documentation建議分批將有可能與下面的結構:

| '(' [row_key relop] ROW relop row_key 
     (OR [row_key relop] ROW relop row_key)* ')' 

因此,構建一個與查詢的,比方說,100個獨立密鑰的脫節:ROW=x OR ROW=y OR...

+0

我會在一秒後回覆試用。 – badc0re

1

請不要爲此使用SCAN_AND_FILTER_ROWS,當您選擇一行時,會導致性能問題。

的一些方法,以使其更快:

  • 創建TableScanner和多行添加到ScanSpec避免發送許多小的網絡消息的開銷(這是丹尼爾·倫肖建議)
  • 如果您行鍵是在一個範圍內,那麼你還可以獲取各種行鍵的
  • 如果你排按鍵都有一個共同的前綴,那麼你可以使用前綴搜索(其中row = ^「前綴」)