1. 程式人生 > >mysql大批量資料插入技巧

mysql大批量資料插入技巧

轉自:https://jingyan.baidu.com/album/95c9d20d61b01dec4f75615a.html?picindex=6
首先我是簡單的寫了一個mysql的迴圈插入資料的SP,具體如下:
這裡寫圖片描述
這是插入100W資料的過程和結果,可以看到是換了55min +20S約3320秒(約300rows/s),看到之後我是隻崩潰,就在網上查了些提速的方法:

  1. 最快的當然是直接 copy 資料庫表的資料檔案(版本和平臺最好要相同或相似);1. 設定 innodb_flush_log_at_trx_commit = 0 ,相對於 innodb_flush_log_at_trx_commit = 1 可以十分明顯的提升匯入速度;2. 使用 load data local infile 提速明顯;3. 修改引數 bulk_insert_buffer_size, 調大批量插入的快取;4. 合併多條 insert 為一條: insert into t values(a,b,c), (d,e,f) ,,,5. 手動使用事物;
    這裡寫圖片描述

    而我建立的是Innodb型別的表,分了128個分割槽。而我依照以上的方法,設定如下:
    這裡寫圖片描述
    可以明顯的看到插入百萬資料是100S左右,速度提升了33倍之多。

速度是提升了不少,那就加大插入的資料量,提升10倍,即插入千萬的資料量,具體的SP如下:

這裡寫圖片描述
可以看到時間差不多是1200s左右,因為欄位加長了,可能也有影響插入的速度。

為了具體驗證,就按千萬行插入,欄位的長度為1000位元組,來檢視結果,具體的SP和結果如下:
這裡寫圖片描述
varchar欄位

欄位的限制在欄位定義的時候有以下規則: a) 儲存限制 varchar 欄位是將實際內容單獨儲存在聚簇索引之外,內容開頭用1到2個位元組表示實際長度(長度超過255時需要2個位元組),因此最大長度不能超過65535。 b) 編碼長度限制 字元型別若為gbk,每個字元最多佔2個位元組,最大長度不能超過32766;   字元型別若為utf8,每個字元最多佔3個位元組,最大長度不能超過21845。   對於英文比較多的論壇 ,使用GBK則每個字元佔用2個位元組,而使用UTF-8英文卻只佔一個位元組。   若定義的時候超過上述限制,則varchar欄位會被強行轉為text型別,併產生warning。 c) 行長度限制   導致實際應用中varchar長度限制的是一個行定義的長度。 MySQL要求一個行的定義長度不能超過65535。若定義的表長度超過這個值,則提示   ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to    change some columns to TEXT or BLOBs。
這裡寫圖片描述


再次升級插入的資料量,提升10倍,看插入的時間及佔用的記憶體,欄位的位元組同樣為1000,具體的SP和結果如下:
這裡寫圖片描述
從上圖可以清楚的看到,插入1億條資料的時間為5hours +20 min+ 56s=19256s,平均插入的條數為(5193 rows/s)。根上次插入1千萬條的時間差不多,再看所耗磁碟空間,用了98G的空間,跟上次插入千萬條資料時的(26G-17G=9G)也是成線性關係的。按照本機500G的磁碟空間,儲存1行1K位元組大小的資料,本機可以儲存理想極限情況下為5億條資料,保守為4~4.5億左右合適,以防其他的應用或者資料庫的UNDO,索引空間佔用。

最後再看一次查詢的時間,上次插入百萬數,查詢資料量的時間

這裡寫圖片描述
因為建立了索引,在查百萬級的資料量時,時間是1秒左右,在資料量上升到千萬時,查詢1億5百萬時,時間為3Min 30S,再插入1億資料,查詢資料量,時間達到27min 43s,可見,不是線性關係,是幾何級增加的。

現在描述叢集環境的測試

叢集:32G記憶體 ,500G硬碟,3臺虛擬機器也就是3個節點:188.188.2.181(主節點,資料節點和SQL節點)、188.188.2.182(資料節點和SQL節點)和188.188.2.183(資料節點和SQL節點)。/root目錄分割槽磁碟空間200G(原先預設的是50G)、插入的資料量為8000KW,所佔磁碟空間為下圖
這裡寫圖片描述
這裡寫圖片描述