如何定位分析執行效率低的 SQL 語句 ?





一. 通過 show status 命令瞭解各SQL的執行頻率


show [session|global] status like “Com_%”;

session:當前連接執行的統計結果
global:上一次數據庫啓動至今的統計結果


常見的執行參數:
Com_select:執行查詢的次數
Com_insert:執行插入的次數
Com_update:執行更新的次數
Com_delete:執行刪除的次數
Com_rows_read:執行查詢的返回行數(舉一反三:inserted、updated、deleted)
Connection:試圖連接Mysql 服務器的次數
Uptime:服務器工作時間
Slow_queries:慢查詢次數

mysql> show global status like "Slow_queries";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Slow_queries  | 0     |
+---------------+-------+
1 row in set




二. 查找定位低效 SQL 語句


可以通過兩個辦法定位效率較低的 SQL 語句:


1、通過慢查詢日誌 slow.log 定位執行效率低的SQL,但是隻能查到執行完的 sql ,
比如:

# Time: 2020-06-17T07:21:27.095287Z
# User@Host: test[test] @  [1.1.1.1]  Id: 1053670
# Query_time:  4884.455628  Lock_time: 0.000117 Rows_sent: 57  Rows_examined: 516215
SET timestamp=1592378487;
select `x`, `xxx`, `xxxx` ...

2、使用 show processlist命令查看當前 Mysql 正在進行的線程,包括線程狀態、是否鎖表

mysql>  show processlist ;
| Id      | User     | Host                  | db             | Command | Time | State        | Info   |
| 1058129 | test | 1.1.1.1:57617    | mytest      | Query         | 3775  | Sending data | select `app ...



三. 通過 explain 分析低效 SQL 語句的執行計劃


查詢到效率低的 sql 語句後,可以通過 explain 分析低效 SQL 的執行計劃。
explain 加在 select 前面,可以獲取到查詢執行計劃。
在做 SQL 調優時,explain 是王道,
可以讓我們檢查到:在什麼位置加索引最好,優化器是否以最佳順序做表連接。


比如:

mysql> explain select * from testtb ;
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------+
|  1 | SIMPLE      | testtb | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   92 |      100 | NULL  |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------+
1 row in set
select_type: 表示select 的類型,常見取值有SIMPLE(簡單表,即不使用表連接或者子查詢)、PRIMARY、UNION、SUBQUERY等。
table: 輸出結果集的表
type: 表示Mysql 的訪問方式(從上到下依次變快)
type=all,全表掃描,Mysql 遍歷全表來找到匹配的行
type=index,Mysql 遍歷整個索引來找到匹配的行
type=range,索引範圍掃面
type=ref,使用非唯一索引掃描或唯一索引的前綴掃描
type=eq_ref,使用唯一索引
type-const/system,單表中最多隻有一個匹配行
type=NUll,MySQL 不用訪問表或者索引就能直接得到結果
possible_key: 表示查詢時可能用到的索引
key: 表示實際用到的索引
key_len: 使用到索引字段的長度
rows: 掃描行的數量
Extra: 執行情況的說明和描述。



四. 通過 show profile 分析低效 SQL 語句


默認不開啓 profile,使用時先開啓 profile

mysql> set profiling=1;
Query OK, 0 rows affected

mysql> select @@profiling;
+-------------+
| @@profiling |
+-------------+
|           1 |
+-------------+
1 row in set

測試獲取錶行數

mysql> select count(*) from testtb;
+----------+
| count(*) |
+----------+
|       1192 |
+----------+
1 row in set

查詢執行時間

mysql> show profiles;
+----------+------------+------------------------------+
| Query_ID | Duration   | Query                        |
+----------+------------+------------------------------+
|        1 |  0.0109785 | select @@profiling           |
|        2 | 0.05502275 | select count(*) from testtb |
+----------+------------+------------------------------+
2 rows in set

查詢每一步的詳細執行時間

mysql> show profile for query 2;
+----------------------+----------+
| Status               | Duration |
+----------------------+----------+
| starting             | 8.2E-5   |
| checking permissions | 5E-6     |
| Opening tables       | 3E-5     |
| init                 | 1.2E-5   |
| System lock          | 5E-6     |
| optimizing           | 0.056635 |  
| statistics           | 5.2E-5   |
| preparing            | 1.2E-5   |
| executing            | 3E-6     |
| Sending data         | 5E-5     |
| end                  | 4E-6     |
| query end            | 1.2E-5   |
| closing tables       | 8E-6     |
| freeing items        | 3.2E-5   |
| cleaning up          | 1.1E-5   |
+----------------------+----------+
15 rows in set



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章