2014-06-23 88 views
0

我寫了一個Python代碼,它從sqlite數據庫迭代讀取數據,對它進行一些計算並將結果作爲新列等寫回到數據庫。但是,涉及通過更新列來寫入數據庫的部分感覺會逐漸變慢和變慢。有沒有其他辦法可以做到同樣的事情,但速度更快?使sqlite3列更新更快

我的代碼的相關部分被帶到下面。在代碼的這一部分中,創建了兩個新列column_I1_和column_I2_,每列都以迭代編號結尾,如column_I1_1,column_I2_1,然後將新結果從相應列表寫入這些列。問題是,考慮到大量的迭代和計算耗時的性質,再加上大量的行(這裏由num值定義,大約11000行),這個工作太慢...

Is there另一種方式,而不是使用更新?因爲我認爲對於更新,每次添加新值時都必須複製該列,這會導致速度減慢。我曾經爲此使用Excel,並且速度更快,但由於電子表格有256列限制,我不得不切換到數據庫。

cur.execute("alter table C add column_I1_%d integer"%iter) #makes a new column indexed by iteration number 
con.commit() 
for e in range(0,num): # num is a given number as input 
    cur.execute("UPDATE C SET column_I1_%d=? WHERE Id=%d"%(iter,e+1),(w[e],)) # w is a list containing some results 
con.commit() 
    # 
cur.execute("alter table C add column_I2_%d integer"%iter) 
con.commit() 
for f in range(num,(2*num)):   
    cur.execute("UPDATE C SET column_I2_%d=? WHERE Id=%d"%(iter,f-num+1),(w[f],)) 
con.commit() 

.....

您的意見是非常讚賞。另外,我是一個相對Python新手,所以請容易對我! :)

+0

你嘗試過'cur.executemany'嗎?這可能會更快... –

+0

@JoranBeasley它更快,但差異非常小。我檢查了每個更新,如果在一個循環中需要15秒,在excutemany形式中它需要14.8秒。總比沒有好,但仍然太多。而奇怪的是,隨着仿真的進行以及數據庫中現有列的數量的增加,它會減慢很多。雖然它寫了相同的行數,但是在迭代13中爲例如相同的操作需要1分鐘而不是15秒。我還沒有完全明白如何降低成本... – user3643087

+0

你有沒有索引?有一些主鍵嗎? –

回答

1

爲了加快對Id柱查找,在其上創建一個索引:

cur.execute("CREATE INDEX MyLittleIndex ON C(Id)"); 

或者,如果Id列中的值爲uniq UE,聲明該列作爲主鍵(自動創建索引):

cur.execute("CREATE TABLE C(Id PRIMARY KEY)"); 

如果值是整數,宣告此列爲INTEGER PRIMARY KEY會有點更有效:

cur.execute("CREATE TABLE C(Id INTEGER PRIMARY KEY)"); 
+0

哇!這將列寫入時間減少了10倍!謝謝!順便說一句,另一個問題是......在每次迭代中寫入特定列到數據庫的時間以迭代次數線性增加。由於列不會被我覆蓋,並且行數相同,我猜想在每次更新時,python都會複製並重新寫入整個數據庫以及新值。它是否正確?如果是這樣,我該如何避免這種情況?此外,我也試着把雜注同步=關閉,但沒有任何區別。 – user3643087

+1

數據庫需要更新表和索引,但它們被組織爲B樹;所需的時間在O(log n)。 –

+0

這應該會讓事情變得更快......如果可以的話,你基本上總是需要某種主鍵 –

0

您可能會考慮調用executemany一次,而不是在循環中調用execute。

例如,考慮下面的代碼,

for e in range(0,num): # num is a given number as input 
    cur.execute("UPDATE C SET column_I1_%d=? WHERE Id=%d"%(iter,e+1),(w[e],)) 

它可以轉化爲以下,

cur.executemany("UPDATE C SET column_I1_%d=? WHERE Id=?"%(iter), zip(w, range(num))) 
+0

它使它走得更快,雖然差異是微不足道的:t1 = 15.3050000668(s),而t2 = 14.7929999828(s)。我們達到了極限? – user3643087