[**]
我們在向資料庫裡批量插入資料的時候,會遇到要將原有主鍵或者unique索引所在記錄更新的情況,而如果沒有主鍵或者unique索引衝突的時候,直接執行插入操作。
這種情況下,有三種方式執行:
直接每條select, 判斷, 然後insert,毫無疑問,這是最笨的方法了,不斷的查詢判斷,有主鍵或索引衝突,執行update,否則執行insert. 資料量稍微大一點這種方式就不行了。
稍微高階一些的方式。
這是mysql自身的乙個語法,使用replace的時候。其語法為:
replace into tablename (f1, f2, f3) values(vf1, vf2, vf3),(vvf1, vvf2, vvf3)
這中語法會自動查詢主鍵或索引衝突,如有衝突,他會先刪除原有的資料記錄,然後執行插入新的資料。
這也是一種方式,mysql的insert操作中也給了一種方式,語法如下:
insert into table (a,b,c) values (1,2,3)
on duplicate key update c=c+1;
在insert時判斷是否已有主鍵或索引重複,如果有,一句update後面的表示式執行更新,否則,執行插入。
第一種方式不說了,replace和insert on duplicate key這兩種方式,哪中效率更高一些呢,畢竟,我們的執行sql,追求的就是高效。
在最終實踐結果中,得到接過如下:
在資料庫資料量很少的時候, 這兩種方式都很快,無論是直接的插入還是有衝突時的更新,都不錯,但在資料庫表的內容數量比較大(如百萬級)的時候,兩種方式就不太一樣了,
首先是直接的插入
操作,兩種的插入效率都略低, 比如直接向表裡插入1000條資料(百萬級的表(innodb引擎)),二者都差不多需要5,6甚至十幾秒。究其原因,我的主機效能是一方面,但在向大資料表批量插入資料的時候,每次的插入都要維護索引的, 索引固然可以提高查詢的效率,但在更新表尤其是大表的時候,索引就成了乙個不得不考慮的問題了。
其次是更新
表,這裡的更新的時候是帶主鍵值的(因為我是從另乙個表獲取資料再插入,要求主鍵不能變)
同樣直接更新1000條資料, replace的操作要比insert on duplicate的操作低太多太多, 當insert瞬間完成(感覺)的時候,replace要7,8s, replace慢的原因我是知道的,在更新資料的時候,要先刪除舊的,然後插入新的,在這個過程中,還要重新維護索引,所以速度慢,但為何insert on duplicate的更新卻那麼快呢。 在向老大請教後,終於知道,insert on duplicate 的更新操作雖然也會更新資料,但其對主鍵的索引卻不會有改變,也就是說,insert on duplicate 更新對主鍵索引沒有影響.因此對索引的維護成本就低了一些(如果更新的字段不包括主鍵,那就要另說了
)。
在向大資料的表裡批量插入(純插入,不更新)的時候, 隨著插入的數量越來越多,會導致越來越慢,這中情況下,因為我們用的innodb表, 有的說使用事務可以增加效率,但執行變化一般,有待考證。
還有說明一下: 當我們執行資料庫的插入和更新操作很慢的時候,不僅僅是語句,主機效能也很重要, 比如記憶體和cpu, 如果是虛擬機器要相應適當調整, 如果在各種優化了之後效率還是很低, 但cpu和記憶體的占用卻不高,那麼就很可能是磁碟的io效能了,這也會導致資料的更新速度慢。
例項:insert into table (a,b,productid) values (1,2,3) on duplicate key update productid = values(productid),
MYSQL避免批量插入重複資料報錯的解決方案
在mysql中,想要批量的插入資料到資料庫,會使用這樣的語句 insert into mytable title,name,date values my title my name my date another title another name another date 但是如果此時資料庫在這...
mysql批量新增重複資料
很多時候我們都需要大量的資料,下面就來講一講mysql如何新增大量資料 此方法效率不一定會高 但是這個方法一定是最簡單的 首先,建一張表,字段沒有要求 測試用,我就隨便準備寫了兩個字段 users表 欄位name和pwd 然後我們事先新增幾條資料 然後我們執行批量新增的語句 insert into ...
mysql批量插入不重複資料
1.設定唯一建 前提是 有唯一建可用,but基本很難有這樣的場景。datum有唯一建。create table datum id int 11 notnull auto increment mid int 11 notnull default 0 rong liang varchar 255 col...