最近MySQL算是給了一個大福利,出了MySQL8.0:
1,新版本有哪些nb的地方呢?先看看,具體性能表現如何待驗證。

- 事務性數據字典,完全脫離了 MyISAM 存儲引擎
- utf8mb4 字符集將成為默認字符集,並支持 Unicode 9
- InnoDB enhancements. innodb性能提升
-
2,為什么直接從5.7飛到了8.0?
可參考:
- With version 8.0, MySQL is jumping several versions in its numbering (from 5.5), due to 6.0 being nixed (混合型) and 7.0 being reserved for the clustering(為集群保留) version of MySQL.
(What’s new in MySQL 8.0 https://www.infoworld.com/article/3228154/sql/whats-new-in-mysql-80.html)
- 事實上,MySQL 5.x 系列已經延續了很多年,從被 Oracle 收購之前就是 5.1,而收購之后一直維持在 5.x,比如 5.5,5.6,5.7 等等。其實,如果按照原本的發布節奏,可以把 5.6.x 當成 6.x,5.7.x 當成 7.x。所以,只是換了版本命名方式而已。
(知乎:MySQL 8.0.0 發布 https://zhuanlan.zhihu.com/p/22476127)
3,性能測試:
INSERT 插入
SSD下多個表的數據插入,這里測試了數據引擎myisam跟innodb,總體來說插入的效率仍然是myisam獲勝,在同時插入5000個表(每個表4列,主要是時間,整型變量等),innodb需3分多鍾,而myisam只需要1分鍾不到;當然這跟他們的存儲機制相關,myisam直接內存上,而innodb需寫入磁盤log后再執行。(具體可參考:https://stackoverflow.com/questions/9744053/mysql-innodb-vs-myisam-inserts)
下圖是myisam下的測試結果:

如果業務只關心插入效率,那么關於insert我們還能做什么優化嗎? 這里MySQL8.0 官方給出了一些建議: https://dev.mysql.com/doc/refman/8.0/en/insert-optimization.html ;
首先,我們需要理解,在插入執行的整個過程中,有這樣一些關鍵的時間點(數字代表所占的比例):
- Connecting: (3)
- Sending query to server: (2)
- Parsing query: (2)
- Inserting row: (1 × size of row)
- Inserting indexes: (1 × number of indexes)
- Closing: (1)
然后,選擇合適的提升方式:
- If you are inserting many rows from the same client at the same time, use INSERT statements with multiple VALUES lists to insert several rows at a time. This is considerably faster (many times faster in some cases) than using separate single-row INSERT statements. If you are adding data to a nonempty table, you can tune the bulk_insert_buffer_size variable to make data insertion even faster. See Section 5.1.7, “Server System Variables”.
一來如上圖所示,采用多個value的形式,同一個表一次多行數據提交,因為減少了提交次數,這個寫入效率有很明顯的提高;另外當對一個非空表進行插入時,也可以通過修改bulk_insert_buffer_size,來提高寫入效率。MyISAM 對於大體積的打包寫入更快,如INSERT ... SELECT, INSERT ... VALUES (...), (...), ..., and LOAD DATA INFILE 。
- 關於bulk_insert_buffer_size, This variable limits the size of the cache tree in bytes per thread. Setting it to 0 disables this optimization. The default value is 8MB.
bulk_insert_buffer_size 的默認值是8MB:

- When loading a table from a text file, use LOAD DATA INFILE. This is usually 20 times faster than using INSERT statements. See Section 13.2.7, “LOAD DATA INFILE Syntax”.
用LOAD DATA INFILE從txt文件中加載表格,通常會比insert快20倍 (666666666)。
- Take advantage of the fact that columns have default values. Insert values explicitly only when the value to be inserted differs from the default. This reduces the parsing that MySQL must do and improves the insert speed.
充分利用默認值, 充分利用默認值, 充分利用默認值 (因為減少了插入值的解析時間);
- See Section 8.5.5, “Bulk Data Loading for InnoDB Tables” for tips specific to InnoDB tables.
通過disable一些功能,比如autocommit模式,唯一性檢測unique_checks,外鍵foreign_key_checks,或者修改一些參數,如innodb_autoinc_lock_mode 等; 具體可參閱, https://dev.mysql.com/doc/refman/8.0/en/optimizing-innodb-bulk-data-loading.html 。
- See Section 8.6.2, “Bulk Data Loading for MyISAM Tables” for tips specific to MyISAM tables.
有一種情況,例如有數據表擁有多個用戶同時寫入:
-
- Connection 1 does 1000 inserts
- Connections 2, 3, and 4 do 1 insert
- Connection 5 does 1000 inserts
如果沒使用鎖 連接2,3,4 會因為寫入量少會先於1,5完成;但是使用鎖的話情況則不一定,但總的寫入時間會快40%以上。另外,修改配置都是可以提高的方法,如key_buffer_size,默認8MB,如果電腦只跑MySQL, MyISAM存儲,那么這個參數key_buffer_size可以設置為內存的四分之一,千萬別太大,千萬別太大,千萬別太大!!!
key_buffer_size參考: https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_key_buffer_size
大體積MyISAM寫入,具體可參考: https://dev.mysql.com/doc/refman/8.0/en/optimizing-myisam-bulk-data-loading.html
INSERT 總結
如果你只關心寫入效率,那么myisam會勝過innodb,組合提交的效率會高不少,適當根據電腦性能及操作系統修改相關配置也有一定的提升,根據不同業務在寫入時加鎖或利用數據庫的默認值也是不錯的方法。
暫時還沒試 load_data_infile,看起來性能似乎比myisam更好,歡迎分享。
