不管對於哪種服務,對於其優化,無非是從兩個方面着手,第一個是對於硬件方面的優化,第二個是對系統以及服務本身的優化。
1、查詢連接MySQL服務器的次數
mysql> show status like 'connections';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Connections | 3 |
+---------------+-------+
1 row in set (0.01 sec)
2、查詢MySQL服務器的運行時間
mysql> show status like 'uptime'; #單位爲秒
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Uptime | 158 |
+---------------+-------+
1 row in set (0.00 sec)
3、查詢操作的次數
mysql> show status like 'com_select';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_select | 1 |
+---------------+-------+
1 row in set (0.00 sec)
4、插入操作的次數
mysql> show status like 'com_insert';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_insert | 2 |
+---------------+-------+
1 row in set (0.00 sec)
5、更新操作的次數
mysql> show status like 'com_update';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_update | 3 |
+---------------+-------+
1 row in set (0.00 sec)
6、刪除操作的次數
mysql> show status like 'com_delete';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_delete | 1 |
+---------------+-------+
1 row in set (0.00 sec)
7、查詢MySQL服務器的慢查詢次數
mysql> show status like 'slow_queries';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Slow_queries | 15 |
+---------------+-------+
1 row in set (0.00 sec)
二、對SQL語句進行分析
1、使用explain關鍵字進行分析
mysql> explain select * from user\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: user #表名
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL #使用哪個列或常數與索引一起使用來查詢記錄
rows: 3
filtered: 100.00
Extra: NULL
1 row in set, 1 warning (0.00 sec)
上面的select_type解釋如下:
Select_type:表示select語句的類型 其中simple 是簡單查詢(不包括連接查詢和子查詢) Primary 主查詢 Union 連接查詢;
2、利用索引來提高查詢效率
mysql> explain select * from stu_info where s_id=3\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: stu_info
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 3 #需要查詢三行才能查到(這個表數據總共也就三行)
filtered: 33.33
Extra: Using where
1 row in set, 1 warning (0.00 sec)
mysql> create index index_1 on stu_info(s_id); # 創建索引
mysql> explain select * from stu_info where s_id=3\G # 再次查詢
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: stu_info
partitions: NULL
type: ref
possible_keys: index_1 #使用的是哪個索引名稱
key: index_1
key_len: 5
ref: const
rows: 1 #創建索引後,查詢1行就查到可
filtered: 100.00
Extra: NULL
1 row in set, 1 warning (0.00 sec)
使用索引注意事項如下:
- 做索引了之後,用 like ‘xx%’ %不在第一位查詢效率最高;
- 若使用多字段索引,除了第一字段查詢最快,其餘不會按索引來,索引不生效;
- 若創建索引所設置的字段,查詢索引組合 or 左右邊的值都是屬於索引設置字段下的值。
關於使用索引,可參考:MySQL 之索引類型
三、profiling分析查詢
通過慢日誌查詢可以知道哪些SQL語句執行效率低下,通過explain我們可以得知SQL語句的具體執行情況,索引使用等,還可以結合show命令查看執行狀態。如果覺得explain的信息不夠詳細,可以同通過profiling命令得到更準確的SQL執行消耗系統資源的信息。 profiling默認是關閉的。可以通過以下語句查看:
1、查看profiling是否開啓
mysql> show variables like '%profiling%';
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| have_profiling | YES |
| profiling | OFF | # OFF表示未開啓
| profiling_history_size | 15 |
+------------------------+-------+
3 rows in set (0.00 sec)
mysql> select @@profiling;
+-------------+
| @@profiling |
+-------------+
| 0 | # 0表示未開啓
+-------------+
1 row in set, 1 warning (0.00 sec)
2、開啓profiling
mysql> set profiling=1; # 開啓
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> select @@profiling; # 查看是否開啓
+-------------+
| @@profiling |
+-------------+
| 1 |
+-------------+
1 row in set, 1 warning (0.00 sec)
3、執行要測試的SQL語句
mysql> select * from stu_info;
+------+--------+--------+
| s_id | s_name | s_into |
+------+--------+--------+
| 1 | 2 | 3 |
| 3 | 4 | 5 |
| 2 | 4 | 5 |
+------+--------+--------+
3 rows in set (0.00 sec)
4、查看SQL語句對應的ID,對其進行分析
mysql> show profiles;
+----------+------------+------------------------+
| Query_ID | Duration | Query |
+----------+------------+------------------------+
| 1 | 0.00016900 | select @@profiling |
| 2 | 0.00018425 | select * from bank |
| 3 | 0.00018475 | select * from stu_info |
+----------+------------+------------------------+
3 rows in set, 1 warning (0.00 sec)
mysql> show profile for query 3; #查詢sql語句的詳細分析
+----------------------+----------+
| Status | Duration |
+----------------------+----------+
| starting | 0.000058 |
| checking permissions | 0.000005 |
| Opening tables | 0.000022 |
| init | 0.000015 |
| System lock | 0.000006 |
| optimizing | 0.000002 |
| statistics | 0.000008 |
| preparing | 0.000007 |
| executing | 0.000001 |
| Sending data | 0.000036 |
| end | 0.000002 |
| query end | 0.000004 |
| closing tables | 0.000004 |
| freeing items | 0.000008 |
| cleaning up | 0.000008 |
+----------------------+----------+
15 rows in set, 1 warning (0.00 sec)
在上面命令的返回結果中,status是profile裏的狀態,duration是status狀態下的耗時,因此我們關注的就是哪個狀態最耗時,這些狀態中哪些可以優化,當然也可以查看更多的信息,比如:CPU等。語法如下:
mysql> show profile block io for query 3\G
mysql> show profile all for query 3\G
除了上面的block io和all以外,還可以換成cpu(顯示用戶cpu時間、系統cpu時間)、ipc(顯示發送和接收相關開銷信息)、page faults(顯示頁面錯誤相關開銷信息)、swaps(顯示交換次數相關開銷的信息)。
注意:測試完成之後,記得要關閉調試功能,以免影響數據庫的正常使用。
注意:測試完成之後,記得要關閉調試功能,以免影響數據庫的正常使用。
注意:測試完成之後,記得要關閉調試功能,以免影響數據庫的正常使用。
四、對數據庫表結構進行優化
對數據庫表結構的優化大概可以從以下幾個方面着手:
- 將字段很多的表分解成多個表,儘量避免表字段過多;
- 增加中間表,合理增加冗餘字段;
- 優化插入記錄的速度;
- 在插入數據之前禁用索引,會讓創建索引不生效,命令: ALTER TABLE table_name DISABLE KEYS;
- 根據實際情況來定,在插入記錄之前禁用唯一性檢查,命令:set unique_checks=0;
- 多條插入數據的命令最好整合爲一條;
- 使用load data infle批量插入數據。
- 對於innodb引擎的表來說,以下幾點可以進行優化:
- 禁用唯一性檢查:set unique_checks=0;
- 禁用外鍵檢查:set foreign_key_checks=0;
- 禁用自動提交:set autocommit=0;
分析表,檢查表和優化表
所謂分析表,就是分析關鍵字的分佈,檢查表就是檢查是否存在錯誤,優化表就是刪除或更新造成的空間浪費。
1、分析表
分析表可以一次分析一個或多個表,在分析期間只能讀,不能進行插入和更新操作。分析表的語法如下:
mysql> analyze table stu_info;
+----------------+---------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+----------------+---------+----------+----------+
| mysql.stu_info | analyze | status | OK |
+----------------+---------+----------+----------+
1 row in set (0.01 sec)
對於上述返回的結果解釋:Table是表名 ,op執行的操作是什麼, msg_type 信息級別(status是正常狀態,info是信息,note注意,warning警告,error錯誤), msg_text 是顯示信息。
2、檢查表
檢查是否存在錯誤,關鍵字統計,檢查視圖是否有錯誤 Check table 表名 option ={quick |fast | medium|extended |changed} Quick 不掃描行,不檢查錯誤連接 Fast 只檢查沒有被正確關閉的表 Medium 掃描行驗證被刪除的連接是有效的,也可以計算各行的關鍵字校驗和。 Extended 對每行所有關鍵字進行全面的關鍵字查找,Changed 只檢查上次檢查後被更改的表和沒有被正確關閉的表,Option只對myisam 有效 對innodb表無效,在執行時會給表加上只讀鎖。
mysql> check table stu_info;
+----------------+-------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+----------------+-------+----------+----------+
| mysql.stu_info | check | status | OK |
+----------------+-------+----------+----------+
1 row in set (0.00 sec)
3、優化表
消除刪除或更新造成的空間浪費,命令語法格式爲:Optimize [local |no_write_to_binlog] table tb1_name …., 優化myisam的表和innodb的表都有效, 但是隻能優化表中的varchar\text\blob數字類型, 執行過程中上只讀鎖。
mysql> optimize table stu_info\G
*************************** 1. row ***************************
Table: mysql.stu_info
Op: optimize
Msg_type: note
Msg_text: Table does not support optimize, doing recreate + analyze instead
*************************** 2. row ***************************
Table: mysql.stu_info
Op: optimize
Msg_type: status
Msg_text: OK
2 rows in set (0.04 sec)