1. 選擇合適的存儲引擎: InnoDBmysql
除非你的數據表使用來作只讀或者全文檢索 (相信如今提到全文檢索,沒人會用 MYSQL 了),你應該默認選擇 InnoDB 。ios
你本身在測試的時候可能會發現 MyISAM 比 InnoDB 速度快,這是由於: MyISAM 只緩存索引,而 InnoDB 緩存數據和索引,MyISAM 不支持事務。可是 若是你使用 innodb_flush_log_at_trx_commit = 2 能夠得到接近的讀取性能 (相差百倍) 。sql
1.1 如何將現有的 MyISAM 數據庫轉換爲 InnoDB:數據庫
複製代碼代碼以下:緩存
mysql -u [USER_NAME] -p -e "SHOW TABLES IN [DATABASE_NAME];" | tail -n +2 | xargs -I '{}' echo "ALTER TABLE {} ENGINE=InnoDB;" > alter_table.sql
perl -p -i -e 's/(search_[a-z_]+ ENGINE=)InnoDB//1MyISAM/g' alter_table.sql
mysql -u [USER_NAME] -p [DATABASE_NAME] < alter_table.sql安全
1.2 爲每一個表分別建立 InnoDB FILE:服務器
複製代碼代碼以下:架構
innodb_file_per_table=1框架
這樣能夠保證 ibdata1 文件不會過大,失去控制。尤爲是在執行 mysqlcheck -o –all-databases 的時候。函數
2. 保證從內存中讀取數據,講數據保存在內存中
2.1 足夠大的 innodb_buffer_pool_size
推薦將數據徹底保存在 innodb_buffer_pool_size ,即按存儲量規劃 innodb_buffer_pool_size 的容量。這樣你能夠徹底從內存中讀取數據,最大限度減小磁盤操做。
2.1.1 如何肯定 innodb_buffer_pool_size 足夠大,數據是從內存讀取而不是硬盤?
方法 1
1 2 3 4 5 6 7 8 9 10 11 12 |
|
發現 Innodb_buffer_pool_pages_free 爲 0,則說明 buffer pool 已經被用光,須要增大 innodb_buffer_pool_size
InnoDB 的其餘幾個參數:
複製代碼代碼以下:
innodb_additional_mem_pool_size = 1/200 of buffer_pool
innodb_max_dirty_pages_pct 80%
方法 2
或者用iostat -d -x -k 1 命令,查看硬盤的操做。
2.1.2 服務器上是否有足夠內存用來規劃
執行 echo 1 > /proc/sys/vm/drop_caches 清除操做系統的文件緩存,能夠看到真正的內存使用量。
2.2 數據預熱
默認狀況,只有某條數據被讀取一次,纔會緩存在 innodb_buffer_pool。因此,數據庫剛剛啓動,須要進行數據預熱,將磁盤上的全部數據緩存到內存中。數據預熱能夠提升讀取速度。
對於 InnoDB 數據庫,能夠用如下方法,進行數據預熱:
1. 將如下腳本保存爲 MakeSelectQueriesToLoad.sql
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
2. 執行
複製代碼代碼以下:
mysql -uroot -AN < /root/MakeSelectQueriesToLoad.sql > /root/SelectQueriesToLoad.sql
3. 每次重啓數據庫,或者整庫備份前須要預熱的時候執行:
mysql -uroot < /root/SelectQueriesToLoad.sql > /dev/null 2>&1
2.3 不要讓數據存到 SWAP 中
若是是專用 MYSQL 服務器,能夠禁用 SWAP,若是是共享服務器,肯定 innodb_buffer_pool_size 足夠大。或者使用固定的內存空間作緩存,使用 memlock 指令。
3. 按期優化重建數據庫
mysqlcheck -o –all-databases 會讓 ibdata1 不斷增大,真正的優化只有重建數據表結構:
1 2 3 4 5 |
|
4. 減小磁盤寫入操做
4.1 使用足夠大的寫入緩存 innodb_log_file_size
可是須要注意若是用 1G 的 innodb_log_file_size ,假如服務器當機,須要 10 分鐘來恢復。
推薦 innodb_log_file_size 設置爲 0.25 * innodb_buffer_pool_size
4.2 innodb_flush_log_at_trx_commit
這個選項和寫磁盤操做密切相關:
innodb_flush_log_at_trx_commit = 1 則每次修改寫入磁盤
innodb_flush_log_at_trx_commit = 0/2 每秒寫入磁盤
若是你的應用不涉及很高的安全性 (金融系統),或者基礎架構足夠安全,或者 事務都很小,均可以用 0 或者 2 來下降磁盤操做。
4.3 避免雙寫入緩衝
複製代碼代碼以下:
innodb_flush_method=O_DIRECT
5. 提升磁盤讀寫速度
RAID0 尤爲是在使用 EC2 這種虛擬磁盤 (EBS) 的時候,使用軟 RAID0 很是重要。
6. 充分使用索引
6.1 查看現有表結構和索引
複製代碼代碼以下:
SHOW CREATE TABLE db1.tb1/G
6.2 添加必要的索引
索引是提升查詢速度的惟一方法,好比搜索引擎用的倒排索引是同樣的原理。
索引的添加須要根據查詢來肯定,好比經過慢查詢日誌或者查詢日誌,或者經過 EXPLAIN 命令分析查詢。
複製代碼代碼以下:
ADD UNIQUE INDEX
ADD INDEX
6.2.1 好比,優化用戶驗證表:
添加索引
複製代碼代碼以下:
ALTER TABLE users ADD UNIQUE INDEX username_ndx (username);
ALTER TABLE users ADD UNIQUE INDEX username_password_ndx (username,password);
每次重啓服務器進行數據預熱
複製代碼代碼以下:
echo 「select username,password from users;」 > /var/lib/mysql/upcache.sql
添加啓動腳本到 my.cnf
複製代碼代碼以下:
[mysqld]
init-file=/var/lib/mysql/upcache.sql
6.2.2 使用自動加索引的框架或者自動拆分表結構的框架
好比,Rails 這樣的框架,會自動添加索引,Drupal 這樣的框架會自動拆分表結構。會在你開發的初期指明正確的方向。因此,經驗不太豐富的人一開始就追求從 0 開始構建,實際是很差的作法。
7. 分析查詢日誌和慢查詢日誌
記錄全部查詢,這在用 ORM 系統或者生成查詢語句的系統頗有用。
複製代碼代碼以下:
log=/var/log/mysql.log
注意不要在生產環境用,不然會佔滿你的磁盤空間。
記錄執行時間超過 1 秒的查詢:
複製代碼代碼以下:
long_query_time=1
log-slow-queries=/var/log/mysql/log-slow-queries.log
8. 激進的方法,使用內存磁盤
如今基礎設施的可靠性已經很是高了,好比 EC2 幾乎不用擔憂服務器硬件當機。並且內存實在是便宜,很容易買到幾十G內存的服務器,能夠用內存磁盤,按期備份到磁盤。
將 MYSQL 目錄遷移到 4G 的內存磁盤
1 2 3 4 5 |
|
9. 用 NOSQL 的方式使用 MYSQL
B-TREE 仍然是最高效的索引之一,全部 MYSQL 仍然不會過期。
用 HandlerSocket 跳過 MYSQL 的 SQL 解析層,MYSQL 就真正變成了 NOSQL。
10. 其餘
單條查詢最後增長 LIMIT 1,中止全表掃描。
將非」索引」數據分離,好比將大篇文章分離存儲,不影響其餘自動查詢。
不用 MYSQL 內置的函數,由於內置函數不會創建查詢緩存。
PHP 的創建鏈接速度很是快,全部能夠不用鏈接池,不然可能會形成超過鏈接數。固然不用鏈接池 PHP 程序也可能將
鏈接數佔滿好比用了 @ignore_user_abort(TRUE);
使用 IP 而不是域名作數據庫路徑,避免 DNS 解析問題
以上就是10個MySQL性能調優的方法,但願對你們的學習有所幫助。