解決 Docker 官方的 MySQL 8 執行 INSERT 超級慢的問題

原本 insert 20 筆資料會耗時 1秒,改完後,insert 500 筆不到 0.1 秒!

注意事項

  • 雖然以下不會執行sql語法,但動到資料庫參數,要確認隨時可以回復到可用狀態。
  • 如果已有 my.cnf 檔,就建立另一個檔

環境

  • 官方的 MySQL 8.4 Docker image (FROM mysql:8)

解法

加入一個自定義 my.cnf 檔在 /etc/mysql/conf.d/ ,內容:

[mysqld]
# 通常設定為系統 RAM 的 60-80%。這裡數值約16G
innodb_buffer_pool_size = 17089934592

# 增大此緩衝區可以提高寫入性能,特別是在處理大量寫入時,會減少磁碟寫入的頻率。
# 這裡數值約256MB
innodb_log_buffer_size  = 268217728

# 是否在每個事務提交後同步二進制日誌(Binary Log)。
# 設置為 1 會增加每個事務的成本,設為 0 或 100 可以提高寫入性能。
sync_binlog = 0

# 事務提交時,何時將日誌寫入磁碟的選項。設為 0 可以減少事務提交的 I/O 負擔,
# 但會犧牲持久性,可能遺失最近 1 秒內的事務記錄。
innodb_flush_log_at_trx_commit = 0

# 停用二進制日誌(Binary Log)
skip-log-bin = 0

 

References

 

以下僅為測試數據

用以下參數,insert 500 筆的時間: 0 分 10.40642 秒

[mysqld]
innodb_buffer_pool_size = 17089934592
innodb_log_buffer_size    = 268217728
# sync_binlog = 0
innodb_flush_log_at_trx_commit = 0
skip-log-bin = 0

用以下參數,insert 500 筆的時間: 0 分 11.31482 秒

[mysqld]
innodb_buffer_pool_size = 17089934592
innodb_log_buffer_size    = 268217728
sync_binlog = 0
# innodb_flush_log_at_trx_commit = 0
skip-log-bin = 0

用以下參數,insert 500 筆的時間: 0 分 0.06932 秒

[mysqld]
innodb_buffer_pool_size = 17089934592
innodb_log_buffer_size    = 268217728
sync_binlog = 0
innodb_flush_log_at_trx_commit = 0
# skip-log-bin = 0

用以下參數,insert 500 筆的時間: 0 分 0.07774 秒

[mysqld]
innodb_buffer_pool_size = 17089934592
innodb_log_buffer_size    = 268217728
sync_binlog = 0
innodb_flush_log_at_trx_commit = 0
skip-log-bin = 0

留言

這個網誌中的熱門文章

電話線四芯或二芯(4C或2C)的差別

開機自動執行 Google Chrome App on Mac OS X

RPi 作業系統的 ntp service 相關