1. 程式人生 > >Mysql高效插入/更新數據

Mysql高效插入/更新數據

from 高效 col don select errorlog 批量 解決 左右

從tushare抓取到的財務數據,最開始只是想存下來,用的辦法想簡單點,是:插入--報錯—update

但發現這個方法太蠢,異常會導致大量無效連接,改為:

        for idx,row in d2.iterrows():
            try:
                rs=db.getData("select f_Code,f_Time,%s from caiwu where f_Code=:1 and f_Time=:2"%fldname,row["code"],dat)
                if len(rs)==0:
                    db.doNonQuery("insert into caiwu (f_Code,f_Time,%s) values(:1,:2,:3)
"%fldname,row["code"],dat,row[colname]) else: if rs[0][2] is None: db.doNonQuery("update caiwu set %s=:1 where f_Code=:2 and f_Time=:3"%fldname,row[colname],row["code"],dat) except: log.errorlogger().exception
("數據入庫錯誤!")

運行沒啥大問題,但就是太慢,取兩年數據,萬條左右,一早上還沒全部入庫。只得研究優化,結果發現mysql居然有專門的語法,可以插入記錄,遇到重復記錄則為自動更新:

ON DUPLICATE KEY UPDATE

上面的處理直接用一條sql語句就解決了:

INSERT INTO TABLE (a,c) VALUES (1,3) ON DUPLICATE KEY UPDATE c=c+1;

然後再進一步,批量入庫也沒問題,還能分別處理:

INSERT INTO TABLE (a,b,c) VALUES 
(1,2,3),
(2,5,7),
(3,3,6),
(4,8,2)
ON DUPLICATE KEY UPDATE b=VALUES(b);

簡直不要太方便:

#數據入庫:
#   d2:待入庫dataframe,第一列為code,第二列為數值
#   dat:時間
#   fldname:數據在庫中的字段名
def addtodb(d2,dat,fldname):    
    i=0
    while i<len(d2): 
        kvs=reduce(lambda x,y:"%s%s(‘%s‘ , ‘%s‘ , %s)"%(x,"" if x=="" else ",",y[0],dat,y[1]),d2.values[i:i+1000],"")
        sqlstr="insert into caiwu (f_Code,f_Time,%s) values %s ON DUPLICATE KEY UPDATE %s=VALUES(%s)"%(fldname,kvs,fldname,fldname)
        try:
            db.doNonQuery(sqlstr)
        except:
            log.errorlogger().exception("數據入庫錯誤!")
        i+=1000    

測試,基本上瞬間入庫!

Mysql高效插入/更新數據