MySQL 調優/優化的 100 個建議

MySQL是一個強大的開源數據庫。隨着MySQL上的應用愈來愈多,MySQL逐漸遇到了瓶頸。這裏提供 101 條優化 MySQL 的建議。有些技巧適合特定的安裝環境,可是思路是相通的。我已經將它們分紅了幾類以幫助你理解。mysql


MySQL監控sql


MySQL服務器硬件和OS(操做系統)調優:數據庫


一、有足夠的物理內存,能將整個InnoDB文件加載到內存裏 —— 若是訪問的文件在內存裏,而不是在磁盤上,InnoDB會快不少。緩存


二、全力避免 Swap 操做 — 交換(swapping)是從磁盤讀取數據,因此會很慢。性能優化


三、使用電池供電的RAM(Battery-Backed RAM)。服務器


四、使用一個高級磁盤陣列 — 最好是 RAID10 或者更高。session


五、避免使用RAID5 — 和校驗須要確保完整性,開銷很高。app


六、將你的操做系統和數據分開,不只僅是邏輯上要分開,物理上也要分開 — 操做系統的讀寫開銷會影響數據庫的性能。性能


七、將臨時文件和複製日誌與數據文件分開 — 後臺的寫操做影響數據庫從磁盤文件的讀寫操做。測試


八、更多的磁盤空間等於更高的速度。


九、磁盤速度越快越好。


十、SAS優於SATA。


十一、小磁盤的速度比大磁盤的更快,尤爲是在 RAID 中。


十二、使用電池供電的緩存 RAID(Battery-Backed Cache RAID)控制器。


1三、避免使用軟磁盤陣列。


14. 考慮使用固態IO卡(不是磁盤)來做爲數據分區 — 幾乎對全部量級數據,這種卡可以支持 2 GBps 的寫操做。


1五、在 Linux 系統上,設置 swappiness 的值爲0 — 沒有理由在數據庫服務器上緩存文件,這種方式在Web服務器或桌面應用中用的更多。


1六、儘量使用 noatime 和 nodirtime 來掛載文件系統 — 沒有必要爲每次訪問來更新文件的修改時間。


1七、使用 XFS 文件系統 — 一個比ext3更快的、更小的文件系統,擁有更多的日誌選項,同時,MySQL在ext3上存在雙緩衝區的問題。


1八、優化你的 XFS 文件系統日誌和緩衝區參數 – -爲了獲取最大的性能基準。


1九、在Linux系統中,使用 NOOP 或 DEADLINE IO 調度器 — CFQ 和 ANTICIPATORY 調度器已經被證實比 NOOP 和 DEADLINE 慢。


20、使用 64 位操做系統 — 有更多的內存能用於尋址和 MySQL 使用。


2一、將不用的包和後臺程序從服務器上刪除 — 減小資源佔用。


2二、將使用 MySQL 的 host 和 MySQL自身的 host 都配置在一個 host 文件中 — 這樣沒有 DNS 查找。


2三、永遠不要強制殺死一個MySQL進程 — 你將損壞數據庫,並運行備份。


2四、讓你的服務器只服務於MySQL — 後臺處理程序和其餘服務會佔用數據庫的 CPU 時間。


MySQL 配置:


2五、使用 innodb_flush_method=O_DIRECT 來避免寫的時候出現雙緩衝區。


2六、避免使用 O_DIRECT 和 EXT3 文件系統 — 這會把全部寫入的東西序列化。


2七、分配足夠 innodb_buffer_pool_size ,來將整個InnoDB 文件加載到內存 — 減小從磁盤上讀。


2八、不要讓 innodb_log_file_size 太大,這樣可以更快,也有更多的磁盤空間 — 常常刷新有利下降發生故障時的恢復時間。


2九、不要同時使用 innodb_thread_concurrency 和 thread_concurrency 變量 — 這兩個值不能兼容。


30、爲 max_connections 指定一個小的值 — 太多的鏈接將耗盡你的RAM,致使整個MySQL服務器被鎖定。


3一、保持 thread_cache 在一個相對較高的數值,大約是 16 — 防止打開鏈接時候速度降低。


3二、使用 skip-name-resolve — 移除 DNS 查找。


3三、若是你的查詢重複率比較高,而且你的數據不是常常改變,請使用查詢緩存 — 可是,在常常改變的數據上使用查詢緩存會對性能有負面影響。


3四、增長 temp_table_size — 防止磁盤寫。


3五、增長 max_heap_table_size — 防止磁盤寫。


3六、不要將 sort_buffer_size 的值設置的過高 — 可能致使鏈接很快耗盡全部內存。


3七、監控 key_read_requests 和 key_reads,以便肯定 key_buffer 的值 — key 的讀需求應該比 key_reads 的值更高,不然使用 key_buffer 就沒有效率了。


3八、設置 innodb_flush_log_at_trx_commit = 0 能夠提升性能,可是保持默認值(1)的話,能保證數據的完整性,也能保證複製不會滯後。


3九、有一個測試環境,便於測試你的配置,能夠常常重啓,不會影響生產環境。



MySQL Schema 優化:


40、保證你的數據庫的整潔性。


4一、歸檔老數據 — 刪除查詢中檢索或返回的多餘的行


4二、在數據上加上索引。


4三、不要過分使用索引,評估你的查詢。


4四、壓縮 text 和 blob 數據類型 — 爲了節省空間,減小從磁盤讀數據。


4五、UTF 8 和 UTF16 比 latin1 慢。


4六、有節制的使用觸發器。


4七、保持數據最小量的冗餘 — 不要複製不必的數據.


4八、使用連接表,而不是擴展行。


4九、注意你的數據類型,儘量的使用最小的。


50、若是其餘數據須要常常須要查詢,而 blob/text 不須要,則將 blob/text 數據域其餘數據分離。


5一、常常檢查和優化表。


5二、常常作重寫 InnoDB 表的優化。


5三、有時,增長列時,先刪除索引,以後在加上索引會更快。


5四、爲不一樣的需求選擇不一樣的存儲引擎。


5五、日誌表或審計表使用ARCHIVE存儲引擎 — 寫的效率更高。


5六、將 session 數據存儲在 memcache 中,而不是 MySQL 中 — memcache 能夠設置自動過時,防止MySQL對臨時數據高成本的讀寫操做。


5七、若是字符串的長度是可變的,則使用VARCHAR代替CHAR — 節約空間,由於CHAR是固定長度,而VARCHAR不是(utf8 不受這個影響)。


5八、逐步對 schema 作修改 — 一個小的變化將產生的巨大的影響。


5九、在開發環境測試全部 schema 變更,而不是在生產環境的鏡像上去作。


60、不要隨意改變你的配置文件,這可能產生很是大的影響。


6一、有時候,少許的配置會更好。


6二、質疑使用通用的MySQL配置文件。



查詢優化:


6三、使用慢查詢日誌,找出執行慢的查詢。


6四、使用 EXPLAIN 來決定查詢功能是否合適。


6五、常常測試你的查詢,看是否須要作性能優化 — 性能可能會隨着時間的變化而變化。


6六、避免在整個表上使用count(*) ,它可能會將整個表鎖住。


6七、保持查詢一致,這樣後續相似的查詢就能使用查詢緩存了。


6八、若是合適,用 GROUP BY 代替 DISTINCT。


6九、在 WHERE、GROUP BY 和 ORDER BY 的列上加上索引。


70、保證索引簡單,不要在同一列上加多個索引。


7一、有時,MySQL 會選擇錯誤的索引,這種狀況使用 USE INDEX。


7二、使用 SQL_MODE=STRICT 來檢查問題。


7三、索引字段少於5個時,UNION 操做用 LIMIT,而不是 OR。


7四、使用 INSERT ON DUPLICATE KEY 或 INSERT IGNORE 來代替 UPDATE,避免 UPDATE 前須要先 SELECT。


7五、使用索引字段和 ORDER BY 來代替 MAX。


7六、避免使用 ORDER BY RAND()。


7七、LIMIT M,N 在特定場景下會下降查詢效率,有節制使用。


7八、使用 UNION 來代替 WHERE 子句中的子查詢。


7九、對 UPDATE 來講,使用 SHARE MODE 來防止排他鎖。


80、重啓 MySQL 時,記得預熱數據庫,確保將數據加載到內存,提升查詢效率。


8一、使用 DROP TABLE ,而後再 CREATE TABLE ,而不是 DELETE FROM ,以刪除表中全部數據。


8二、最小化你要查詢的數據,只獲取你須要的數據,一般來講不要使用 *。


8三、考慮持久鏈接,而不是屢次創建鏈接,已減小資源的消耗。


8四、基準查詢,包括服務器的負載,有時一個簡單的查詢會影響其餘的查詢。


8五、當服務器的負載增長時,使用SHOW PROCESSLIST來查看慢的/有問題的查詢。


8六、在存有生產環境數據副本的開發環境中,測試全部可疑的查詢。



MySQL備份過程:


8七、在二級複製服務器上進行備份。


8八、備份過程當中中止數據的複製,以防止出現數據依賴和外鍵約束的不一致。


8九、完全中止MySQL以後,再從數據文件進行備份。


90、若是使用MySQL dump進行備份,請同時備份二進制日誌 — 確保複製過程不被中斷。


9一、不要信任 LVM 快照的備份 — 可能會建立不一致的數據,未來會所以產生問題。


9二、爲每一個表作一個備份,這樣更容易實現單表的恢復 — 若是數據與其餘表是相互獨立的。


9三、使用 mysqldump 時,指定 -opt 參數。


9四、備份前檢測和優化表。


9五、臨時禁用外鍵約束,來提升導入的速度。


9六、臨時禁用惟一性檢查,來提升導入的速度。


9七、每次備份完後,計算數據庫/表數據和索引的大小,監控其增加。


9八、使用定時任務(cron)腳本,來監控從庫複製的錯誤和延遲。


9九、按期備份數據。


100、按期測試備份的數據。

相關文章
相關標籤/搜索