(1)提高資料庫插入效能中心思想:盡量將資料一次性寫入到Data File和減少資料庫的checkpoint 操作。這次修改了下面四個配置項:
1)將 innodb_flush_log_at_trx_commit 配置設定為0;按過往經驗設定為0,插入速度會有很大提高。
0: Write the log buffer to the log file and flush the log file every second, but do nothing at transaction commit.
1:the log buffer is written out to the log file at each transaction commit and the flush to disk operation is performed on the log file
2:the log buffer is written out to the file at each commit, but the flush to disk operation is not performed on it
2)將 innodb_autoextend_increment 配置由於預設8M 調整到 128M
此配置項作用主要是當tablespace 空間已經滿了後,需要MySQL系統需要自動擴充多少空間,每次tablespace 擴充都會讓各個SQL 處於等待狀態。增加自動擴充Size可以減少tablespace自動擴充次數。
3)將 innodb_log_buffer_size 配置由於預設1M 調整到 16M
此配置項作用設定innodb 資料庫引擎寫日誌緩衝區;將此緩衝段增大可以減少資料庫寫資料檔案次數。
4)將 innodb_log_file_size 配置由於預設 8M 調整到 128M
此配置項作用設定innodb 資料庫引擎UNDO日誌的大小;從而減少資料庫checkpoint操作。
經過以上調整,系統插入速度由於原來10分鐘幾萬條提升至1秒1W左右;註:以上參數調整,需要根據不同機器來進行實際調整。特別是 innodb_flush_log_at_trx_commit、innodb_log_buffer_size和 innodb_log_file_size 需要謹慎調整;因為涉及MySQL本身的容災處理。
(2)提升資料庫讀取速度,重資料庫層面上讀取速度提升主要由於幾點:簡化SQL、加索引和分區; 經過檢查程式SQL已經是最簡單,查詢條件上已經增加索引。我們只能用武器:表分區。
資料庫 MySQL分區前準備:在MySQL中,資料表空間就是儲存資料和索引的資料檔案。
將S11資料庫由於同享tablespace 修改為支援多個tablespace;
將wb_user_info_sina 和 wb_user_info_tx 兩個表修改為各自獨立資料表空間;(Sina:1700W資料,2.6G 大資料檔案,Tencent 1400W,2.3G大資料檔案);
分區操作:
將現有的主鍵和索引先刪除
重現建立id,uid 的聯合主鍵
再以 uid 為索引值進行分區。這時候到/var/data/mysql 查看資料檔案,可以看到兩個大表各自獨立資料表空間已經分割成若干個較少獨立分區空間。(這時候若以uid 為檢索條件進行查詢,並不提升速度;因為索引值只是安排資料存放區的分區並不會建立分區索引。我非常鬱悶這點比Oracle 差得不是一點半點鐘。)
再以 uid 欄位上進行建立索引。再次到/var/data/mysql 檔案夾查看資料檔案,非常鬱悶地發現各個分區Size竟然大了。MySQL還是老樣子將索引與資料存放區在同一個tablespace裡面。若能index 與 資料分離能夠更加好管理。
經過以上調整,暫時沒能體現出系統讀取速度提升;基本都是在 2~3秒完成5K資料更新。
MySQL資料庫插入速度調整補充資料:
MySQL 從最開始的時候 1000條/分鐘的插入速度調高至 10000條/秒。 相信大家都已經等急了相關介紹,下面我做調優時候的整個過程。提高資料庫插入效能中心思想:
1、盡量使資料庫一次性寫入Data File
2、減少資料庫的checkpoint 操作
3、程式上盡量緩衝資料,進行批量式插入與提交
4、減少系統的IO衝突
根據以上四點內容,作為一個業餘DBA對MySQL服務進行了下面調整:
修改負責收錄記錄MySQL伺服器配置,提升MySQL整體寫速度;具體為下面三個資料庫變數值:innodb_autoextend_increment、innodb_log_buffer_size、innodb_log_file_size;此三個變數預設值分別為 5M、8M、8M,根據伺服器記憶體大小與具體使用方式,將此三隻分別修改為:128M、16M、128M。同時,也將原來2個 Log File 變更為 8 個Log File。此次修改主要滿足第一和第二點,如:增加innodb_autoextend_increment就是為了避免由於頻繁自動擴充Data File而導致 MySQL 的checkpoint 操作;
將大錶轉變為獨立表空並且進行分區,然後將不同分區下掛在多個不同硬碟陣列中。
完成了以上修改操作後;我看到下面幸福結果:
擷取測試結果:
Query OK, 2500000 rows affected (4 min 4.85 sec)
Records: 2500000 Duplicates: 0 Warnings: 0
Query OK, 2500000 rows affected (4 min 58.89 sec)
Records: 2500000 Duplicates: 0 Warnings: 0
Query OK, 2500000 rows affected (5 min 25.91 sec)
Records: 2500000 Duplicates: 0 Warnings: 0
Query OK, 2500000 rows affected (5 min 22.32 sec)
Records: 2500000 Duplicates: 0 Warnings: 0
最後表的資料量:
+------------+
| count(*) |
+------------+
| 10000000|
+------------+
從上面結果來看,資料量增加會對插入效能有一定影響。不過,整體速度還是非常面議。一天不到時間,就可以完成4億資料正常處理。預計資料庫瓶頸已經被巧妙解決,結果變成程式“猿”苦逼地向我埋怨,大哥不用這麼狠啊。