MySQL 的性能(上篇)—— SQL 執行分析


簡介

文中內容均為閱讀前輩的文章所整理而來,參考文章已在最后全指明

本文分為上下兩篇:

后端開發必然會接觸到數據庫,數據層的優劣會影響整個服務的響應時間。所以,數據庫的優化技巧是必須掌握的,下面就是我在學習過程中整理的,備忘。

下面為上篇內容,分為以下部分:

  • 一、SQL 執行時間分析
  • 二、SQL 執行情況分析

一、SQL 執行時間分析

通過找到執行時間長的 SQL 語句,可以直觀的發現數據層的效率問題。

1.通過 show processlist 來查看系統的執行情況

mysql> show processlist;
+----+------+-----------+------+---------+------+-------+------------------+
| Id | User | Host      | db   | Command | Time | State | Info             |
+----+------+-----------+------+---------+------+-------+------------------+
|  2 | root | localhost | NULL | Query   |    0 | init  | show processlist |
+----+------+-----------+------+---------+------+-------+------------------+
1 row in set (0.01 sec)

2.通過 profiling 來進行查看

這個命令是查看 SQL 的執行時間,能很直觀的看出快慢。

2.1 查看 profiling 是否開啟

0 代表還是關閉着分析功能

mysql> select @@profiling;
+-------------+
| @@profiling |
+-------------+
|           0 |
+-------------+

2.2 打開工具

mysql> set profiling=1;
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> select @@profiling;
+-------------+
| @@profiling |
+-------------+
|           1 |
+-------------+

2.3 查看 SQL 的執行時間

mysql> show profiles;
+----------+------------+----------------------------+
| Query_ID | Duration   | Query                      |
+----------+------------+----------------------------+
|        1 | 0.00173700 | select * from ip           |
|        2 | 0.00057500 | select porxy, port from ip |
+----------+------------+----------------------------+

2.4 查看 SQL 執行耗時詳細信息

語法:show profile for query Query_ID

mysql> show profile for query 1;
+----------------------+----------+
| Status               | Duration |
+----------------------+----------+
| starting             | 0.000073 |
| checking permissions | 0.000031 |   ---檢查是否在緩存中  
| Opening tables       | 0.000207 |   ---打開表
| init                 | 0.000067 |   ---初始化
| System lock          | 0.000040 |   ---鎖系統
| optimizing           | 0.000005 |   ---優化查詢
| statistics           | 0.000021 |
| preparing            | 0.000015 |   ---准備
| executing            | 0.000003 |   ---執行
| Sending data         | 0.000993 |
| end                  | 0.000006 |
| query end            | 0.000007 |
| closing tables       | 0.000011 |
| freeing items        | 0.000169 |
| cleaning up          | 0.000089 |
+----------------------+----------+

以上具體的信息都是從 INFORMATION_SCHEMA.PROFILING 這張表中取得的。這張表記錄了所有的各個步驟的執行時間及相關信息。語法:
select * from INFORMATION_SCHEMA.PROFILING where query_id = Query_ID;

3.慢查詢日志

MySQL 的慢查詢日志,顧名思義就是把執行時間超過設定值(默認為10s)的 SQL 記錄到日志中。這項功能需要手動開啟,但是開啟后會造成一定的性能損耗。

3.1 查看慢日志是否開啟

默認情況下slow_query_log的值為OFF,表示慢查詢日志是禁用的,可以通過設置slow_query_log的值來開啟。語法:set global slow_query_log=1

mysql> show variables  like '%slow_query_log%';
+---------------------+------------------------------------------------------+
| Variable_name       | Value                                                |
+---------------------+------------------------------------------------------+
| slow_query_log      | OFF                                                  |
| slow_query_log_file | /usr/local/var/mysql/xueweihandeMacBook-Air-slow.log |
+---------------------+------------------------------------------------------+
2 rows in set (0.11 sec)

mysql> set global slow_query_log=1;
Query OK, 0 rows affected (0.03 sec)

mysql> show variables  like '%slow_query_log%';
+---------------------+------------------------------------------------------+
| Variable_name       | Value                                                |
+---------------------+------------------------------------------------------+
| slow_query_log      | ON                                                   |
| slow_query_log_file | /usr/local/var/mysql/xueweihandeMacBook-Air-slow.log |
+---------------------+------------------------------------------------------+

3.2 設置超時時間

  • 設置語法:set global long_query_time=4
  • 查看語法:show variables like 'long_query_time'

注意:修改后,需要重新連接或新開一個會話才能看到修改值。

永久生效,修改 my.cnf

slow_query_log=1
long_query_time=10
slow_query_log_file=/path/mysql_slow.log

3.3 其他參數

3.3.1 log_output

參數是指定日志的存儲方式。log_output='FILE'表示將日志存入文件,默認值是'FILE'。log_output='TABLE'表示將日志存入數據庫,這樣日志信息就會被寫入到mysql.slow_log表中。MySQL數據庫支持同時兩種日志存儲方式,配置的時候以逗號隔開即可,如:log_output='FILE,TABLE'。日志記錄到系統的專用日志表中,要比記錄到文件耗費更多的系統資源,因此對於需要啟用慢查詢日志,又需要能夠獲得更高的系統性能,那么建議優先記錄到文件。

3.3.2 log-queries-not-using-indexes

未使用索引的查詢也被記錄到慢查詢日志中(可選項)。如果調優的話,建議開啟這個選項。另外,開啟了這個參數,其實使用full index scan的sql也會被記錄到慢查詢日志。

3.3.3 log_slow_admin_statements

表示是否將慢管理語句例如ANALYZE TABLE和ALTER TABLE等記入慢查詢日志

3.4 分析工具 mysqldumpslow

MySQL 提供了慢日志分析工具 mysqldumpslow。

  • -s 表示按照何種方式排序;
    • c: 訪問計數
    • l: 鎖定時間
    • r: 返回記錄
    • t: 查詢時間
    • al:平均鎖定時間
    • ar:平均返回記錄數
    • at:平均查詢時間
  • -t 是top n的意思,即為返回前面多少條的數據;
  • -g 后邊可以寫一個正則匹配模式,大小寫不敏感的;

3.4.1 命令示例

  • 得到返回記錄集最多的 10 個 SQL:mysqldumpslow -s r -t 10 /database/mysql/mysql06_slow.log

  • 得到訪問次數最多的 10 個 SQL:mysqldumpslow -s c -t 10 /database/mysql/mysql06_slow.log

  • 得到按照時間排序的前10條里面含有左連接的查詢語句:mysqldumpslow -s t -t 10 -g “left join” /database/mysql/mysql06_slow.log

  • 另外建議在使用這些命令時結合 | 和 more 使用 ,否則有可能出現刷屏的情況:mysqldumpslow -s r -t 20 /mysqldata/mysql/mysql06-slow.log | more

二、SQL 執行情況分析

使用 explain 分析 SQL 執行情況。

explain select * from ip;

+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
|  1 | SIMPLE      | ip    | ALL  | NULL          | NULL | NULL    | NULL |  400 | NULL  |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
select_type table type possible_keys key key_len rows Extra
表示查詢的類型 輸出結果集的表 表示表的連接類型 表示查詢時,可能使用的索引 表示實際使用的索引 索引字段的長度 掃描出的行數(估算的行數) 執行情況的描述和說明

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM