若要最佳化 InnoDB
交易處理,請找出交易功能效能負擔與伺服器工作負載之間的理想平衡。例如,如果應用程式每秒提交數千次,可能會遇到效能問題;如果應用程式每隔 2-3 小時才提交一次,則會遇到不同的效能問題。
預設的 MySQL 設定
AUTOCOMMIT=1
可能會對繁忙的資料庫伺服器造成效能限制。在實際情況允許下,請將數個相關的資料變更操作包裝到單一交易中,方法是發出SET AUTOCOMMIT=0
或START TRANSACTION
語句,然後在完成所有變更後發出COMMIT
語句。如果交易修改了資料庫,
InnoDB
必須在每次交易提交時將日誌刷新到磁碟。當每個變更後接著提交時(如預設的自動提交設定),儲存裝置的 I/O 輸送量會限制每秒可能的操作次數。或者,對於僅包含單一
SELECT
語句的交易,啟用AUTOCOMMIT
有助於InnoDB
識別唯讀交易並加以最佳化。如需需求,請參閱 第 10.5.3 節「最佳化 InnoDB 唯讀交易」。避免在插入、更新或刪除大量列後執行復原。如果大型交易正在降低伺服器效能,則復原可能會使問題更糟,所需時間可能比原始資料變更操作長數倍。終止資料庫程序沒有幫助,因為復原會在伺服器啟動時重新開始。
為盡量減少發生此問題的機會
增加緩衝池的大小,以便將所有資料變更快取,而不是立即寫入磁碟。
設定
innodb_change_buffering=all
,以便除了插入之外,還可以緩衝更新和刪除操作。考慮在大型資料變更操作期間定期發出
COMMIT
語句,可能會將單一刪除或更新分成對較少列進行操作的多個語句。
若要擺脫失控的復原,一旦發生,請增加緩衝池,使復原成為 CPU 繫結並快速執行,或終止伺服器並使用
innodb_force_recovery=3
重新啟動,如第 17.18.2 節「InnoDB 復原」中所述。如果可以承受在發生意外結束時遺失一些最新提交的交易,您可以將
innodb_flush_log_at_trx_commit
參數設定為 0。InnoDB
嘗試每秒刷新一次日誌,儘管無法保證刷新。當資料列被修改或刪除時,這些資料列以及相關的還原日誌不會立即被實際移除,甚至在交易提交後也不會立即移除。舊的資料會被保留,直到更早開始或同時進行的交易完成為止,這樣那些交易才能存取被修改或刪除資料列的先前狀態。因此,一個長時間執行的交易可能會阻止
InnoDB
清除由其他交易變更的資料。當在長時間執行的交易中修改或刪除資料列時,使用
READ COMMITTED
和REPEATABLE READ
隔離層級的其他交易,如果讀取相同的資料列,則必須執行更多工作來重建較舊的資料。當一個長時間執行的交易修改表格時,來自其他交易的針對該表格的查詢不會使用覆蓋索引技術。通常可以從輔助索引檢索所有結果列的查詢,反而會從表格資料中查找適當的值。
如果發現輔助索引頁面的
PAGE_MAX_TRX_ID
過新,或者輔助索引中的記錄被標記為刪除,InnoDB
可能需要使用叢集索引來查找記錄。