起因:有乙個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;
· 如果你在第二個鍵上有unique約束,你可以在匯入會話中暫時關閉唯一性檢查以加速表的匯入:
set unique_checks=0;
對於大表,這節約了大量磁碟i/o,因為innodb可以使用它的插入緩衝來在一批內寫第二個索引記錄。
· 如果你對你的表有foreign key約束,你可以在匯入會話過程中通過關閉外來鍵檢查來提速表的匯入:
set foreign_key_checks=0;
對於大表,這可以節約大量的磁碟i/o。
· 如果你經常有對不經常更新的表的重發查詢,請使用查詢快取:
[mysqld]
query_cache_type = on
query_cache_size = 10m
mysql innodb 效能優化
預設情況下,innodb的引數設定的非常小,在生產環境中遠遠不夠用 比如最重要的兩個引數 innodb buffer pool size 預設是8m innodb flush logs at trx commit 預設設定的是1 也就是同步重新整理log 可以這麼理解 innodb buffer p...
mysql innodb 效能優化
預設情況下,innodb的引數設定的非常小,在生產環境中遠遠不夠用 比如最重要的兩個引數 innodb buffer pool size 預設是8m innodb flush logs at trx commit 預設設定的是1 也就是同步重新整理log 可以這麼理解 innodb buffer p...
MySQL innoDB資料插入效能優化
起因 有乙個innodb引擎的表table,在乙個大概3000次的foreach迴圈中執行 insert into table columna,columnb values valuea,valueb 結果居然超出了60s的php執行限制 當然這個限制可以在php.ini中修改 讓我很不解為何插入效...