1. 程式人生 > >MySQL innoDB資料插入效能優化

MySQL innoDB資料插入效能優化

起因:有一個innoDB引擎的表Table,在一個大概3000次的foreach迴圈中執行

INSERT INTO Table(columnA, columnB) VALUES (valueA, valueB)
結果居然超出了60S的php執行限制(當然這個限制可以在php.ini中修改),讓我很不解為何插入效率如此低下。

經過查詢資料以及摸索,得到以下優化方法:

1、innoDB是mysql引擎中唯一支援事務transaction的引擎。預設所有使用者行為都在事務內發生。
預設mysql建立新連線時,innoDB採用自動提交autocommit模式,每個SQL語句在它自己上形成一個單獨的事務,即insert一次就commit了一次,InnoDB在該事務提交時必須重新整理日誌到磁碟,因此效率受限於磁碟讀寫效率。

你可以通過
mysql_query("SET AUTOCOMMIT = 0");
來關閉自動提交模式。

如 果自動提交模式被關閉,那麼我們可以認為一個使用者總是有一個事務開啟著。一個SQL COMMIT或ROLLBACK語句結束當前事務並且一個新事務開始。兩個語句都釋放所有在當前事務中被設定的InnoDB鎖定。一個COMMIT語句意 味著在當前事務中做的改變被生成為永久的,並且變成其它使用者可見的。一個ROLLBACK語句,在另一方面,撤銷所有當前事務做的修改。
當然如果是自動提交模式,通過用明確的START TRANSACTION或BEGIN語句來開始一個事務,並用COMMIT或者ROLLBACK語句來結束它,這樣使用者仍舊可以執行一個多重語句事務。


2、因此對於本例,在建立資料庫連線後,立即關閉自動提交,在foreach迴圈結束後,一次commit即可,效率大大提升。

mysql_query("SET AUTOCOMMIT = 0");
foreach(***)
  INSERT INTO Table(columnA, columnB) VALUES (valueA, valueB)
mysql_query("commit");

3、對於多次insert行到同一表的需求,你還可以採用多行插入語法來減少客戶端和伺服器之間的通訊開支。


INSERT INTO Table(columnA, columnB) VALUES (1,2), (5,5), (3,3), ...

4、如果你的表有索引,索引會拖慢insert速度。大量插入資料時,可以先關閉索引,然後再重建索引。


ALTER TABLE Table DISABLE KEYS;
INSERT INTO ***;
ALTER TABLE Table ENABLE KEYS;