2012-06-14 62 views
4

我想更新從CSV文件值的數據庫,下面是我的代碼:的Python MySQLdb的在更新緩慢值

import MySQLdb as mdb 
import sys 
import csv 

con = None 
command = '' 
new_name_list = [] 
old_name_list = [] 
duplicates = [] 
update_list = [] 
file = 'csv_file.csv' 
listReader = csv.reader(open(file, 'r')) 
for row in listReader: 
    new_name_list.append(row) 

try: 

    con = mdb.connect('localhost', 'root', 'mypassword', 'mydb') 
    con.autocommit(True) 

    cur = con.cursor() 
    cur.execute("SELECT fil_name FROM file WHERE fil_name like 'boy%' and fil_job_id=1")  

    numrows = int(cur.rowcount) 

    for i in range(numrows): 
     file_name = cur.fetchone() 
    old_name_list.append(file_name[0]) 

    d = dict(new_name_list) 

    for n in old_name_list: 
     try: 
      print n + " has been updated to " + d[n] 
      command = "UPDATE file SET fil_name='" + d[n] + "' WHERE fil_name='" + n + "'" 
      cur.execute(command) 
     except KeyError: 
      duplicates.append(n) 

except mdb.Error, e: 

    print "Error %d: %s" % (e.args[0],e.args[1]) 
    sys.exit(1) 

finally:  

    if con:  
     con.close() 

大約需要2-3秒的每個打印出現,這導致我認爲更新執行正在緩慢進行。我有很多值需要更新,這不應該是它應該執行的速度(假設我能夠快速打印所有d[n]的值)

有沒有辦法加快更新?

編輯:數據庫採用InnoDB引擎

+1

你確定它每循環運行2-3秒,而不僅僅是緩慢地刷新sys.stdout嗎?您是否在每次打印語句後嘗試添加'sys.stdout.flush()'? – jdi

回答

2

根據您的描述,每張打印花費2〜3秒,所以我認爲這個問題可能是這樣的:

  1. 你有你的FIL_NAME列的表文件索引?
  2. 你讓auto_commit成爲true,每次更新都是提交的事務。

如果情況是1,只需在該列上創建索引,不要在更新時進行表掃描。

如果是2,@戴夫給出了一個很好的答案。

+0

如何檢查是否索引,如果不是,我該怎麼做? – androidnoob

+0

1,show table from table_name:http://dev.mysql.com/doc/refman/5.0/en/show-index.html – yancl

+0

2,在table_name(index_col_name)上創建索引index_name:http://dev.mysql .com/doc/refman/5.1/de/create-index.html – yancl

8

你可以嘗試使用executemany

data = [(n, d[n]) for n in old_name_list] 
cur.executemany("UPDATE file SET fil_name='%s' WHERE fil_name='%s'", data) 

此外,你可能要考慮索引fil_name(假設fil_name是讀爲主)

+1

這些''?''應該是''%s'嗎? – jdi

+0

@jdi是的,他們應該,謝謝! – dave

+0

Upvoted!這可能是一個巨大的表現建議。它實際上涉及兩個問題。進行批量查詢,並使用參數代替字符串連接。您可能還會添加OP確保「fil_name」字段已編入索引的建議 – jdi