[TOC]html
最後修改時間: 2019年10月21日15:08:59mysql
查看當前線程處理狀況, 確認當前有哪些語句在執行, 執行狀況如何.git
特別注意執行時間長的, 若是肯定有問題, 那麼可使用 kill {id}
幹掉該鏈接算法
show full processlist
等價於如下語句sql
select id, db, user, host, command, time, state, info from information_schema.processlist order by time desc;
注意:數據庫
show processlist
時, root帳號能夠看到全部帳號的鏈接, 若是是普通帳號則只能看到本身的鏈接.\G
, 即 show full processlist\G
, 來將顯示結果縱向輸出, 方便查看.擴展.
\g
等價於分號緩存
\G
是將顯示的表格以縱向輸出, 方便查看.服務器
慢查詢日誌用於記錄執行時間超過指定閥值的SQL命令.ide
mysql> show variables like 'slow_query_log%'; +---------------------+------------------------------------------------+ | Variable_name | Value | +---------------------+------------------------------------------------+ | slow_query_log | ON | | slow_query_log_file | C:\laragon\data\mysql\DESKTOP-C1GGBS1-slow.log | +---------------------+------------------------------------------------+ mysql> show variables like 'long_query_time'; +-----------------+----------+ | Variable_name | Value | +-----------------+----------+ | long_query_time | 1.000000 | +-----------------+----------+
配置文件工具
############### 慢查詢日誌 ################ # 打開慢查詢日誌 slow_query_log=1 # 日誌記錄位置 log_output=file # 慢查詢日誌記錄文件 slow_query_log_file=/var/run/mysqld/mysqld-slow.log # 慢查詢時間閥值 long_query_time=10
命令方式(mysqld實例重啓後失效)
-- 必須全局開啓慢查詢日誌記錄 set global slow_query_log=1; -- 設置慢查詢時間閥值 set global long_query_time=1;
若是想要分析一些語句的執行, 則能夠考慮將當前Session的慢查詢時間閥值設爲0
set long_query_time=0;
當數據庫被拖垮時(高負載), 任何簡單的語句均可能執行超時, 此時的慢查詢日誌能提供的幫助就有限了.
在實際生產環境中,若是要手工分析日誌,查找、分析SQL,顯然是個體力活,MySQL提供了日誌分析工具mysqldumpslow
# 分析慢日誌 mysqldumpslow -a -n 50 -s c /var/run/mysqld/mysqld-slow.log # 參數說明 --verbose 版本 --debug 調試 --help 幫助 -v 版本 -d 調試模式 -s ORDER 排序方式, 默認是 'at' what to sort by (al, at, ar, c, l, r, t), 'at' is default al: average lock time 平均鎖定時間 ar: average rows sent 平均返回記錄數 at: average query time 平均查詢時間 c: count 訪問計數 l: lock time 鎖定時間 r: rows sent 返回記錄 t: query time 查詢時間 -r 反轉順序,默認文件倒序拍。reverse the sort order (largest last instead of first) -t NUM 顯示前N條 -a 不要將SQL中數字轉換成N,字符串轉換成S。don't abstract all numbers to N and strings to 'S' -n NUM abstract numbers with at least n digits within names -g PATTERN 正則匹配;grep: only consider stmts that include this string -h HOSTNAME mysql機器名或者IP;hostname of db server for *-slow.log filename (can be wildcard), default is '*', i.e. match all -i NAME name of server instance (if using mysql.server startup script) -l 總時間中不減去鎖定時間;don't subtract lock time from total time
示例
獲得返回記錄集最多的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 能夠幫助瞭解:
舉例
<u>字段 id</u>
SQL 執行順序是根據
<u>字段 select_type(查詢類型)</u>
查詢類型 | 說明 |
---|---|
SIMPLE | 簡單查詢 不包含UNION查詢或子查詢 |
PRIMARY | 最外層查詢 查詢中若 包含任何複雜的子部分,最外層查詢則被標記爲PRIMARY |
SUBQUERY | 子查詢 在 SELECT 或 WHERE 中包含了子查詢 |
DEPENDENT SUBQUERY | !!! 子查詢, 但依賴於外層查詢的結果 注意確認, 避免大表驅動小表 |
DERIVED | 子查詢 在 FROM 列表中包含的子查詢被標記爲 DERIVED(衍生) |
UNION | 聯合 UNION 若第二個SELECT出如今UNION以後,則被標記爲UNION |
UNION RESULT | 使用聯合的結果 從UNION表獲取結果的SELECT |
關於UNION, 網上有寫如下這段, 但我我的不理解UNION 若第二個SELECT出如今UNION以後,則被標記爲UNION:若UNION包含在FROM子句的子查詢中,外層SELECT將被標記爲:DERIVED
<u>字段 table(數據表)</u>
訪問的數據表
<u>字段 partitions(分區)</u>
匹配的分區
<u>字段 type(訪問方式)</u>
查詢時的訪問方式, 性能:all < index < range < index_merge < ref < eq_ref < system/const
通常來講至少須要保證訪問方式是 range, 最好是 ref 級別.
訪問方式 | 說明 |
---|---|
ALL | 全表掃描,對於數據表從頭至尾找一遍select * from tb1; 特別的:若是有limit限制,則找到以後就不在繼續向下掃描 select * from tb1 where email = 'seven@live.com' select * from tb1 where email = 'seven@live.com' limit 1; 雖然上述兩個語句都會進行全表掃描,第二句使用了limit,則找到一個後就再也不繼續掃描。 |
INDEX | 全索引掃描,對索引從頭至尾找一遍 由於非主鍵索引樹比較小, 因此會比 ALL 更快 |
RANGE | 對索引列進行範圍查找 一般是在索引樹上快速定位到某一索引項, 再向左/右遍歷. |
INDEX_MERGE | 合併索引,使用多個單列索引搜索, 最後結果取交集或並集 好比使用了UNION 且單獨用到了兩個索引. |
REF | 使用索引快速定位(根據索引查找一個或多個值), 該索引是 普通索引 或 惟一索引的部分前綴 |
EQ_REF | 使用主鍵索引或惟一索引快速定位 一般出如今多表的join查詢, 鏈接時使用primary key 或 unique 索引(都只能匹配到一行記錄) |
CONST | 經過主鍵或惟一索引精確查找到一行 常量 表最多有一個匹配行(主鍵或惟一索引),由於僅有一行,在這行的列值可被優化器剩餘部分認爲是常數,const表很快,由於它們只讀取一次 |
SYSTEM | 系統 表僅有一行, 這是const聯接類型的一個特例, 能夠忽略這種狀況。 |
Q. ALL 和 INDEX 的區別
A. 兩個都是全索引掃描, 不一樣的是 ALL 是對主鍵索引掃描, INDEX 是對非主鍵索引掃描.
這裏要理解, 所謂的全表掃描指的是對主鍵索引掃描.
Q. EQ_REF
和 CONST
的區別
A. 相同點都是使用主鍵/惟一索引精確查找到行記錄. 不一樣點在於:
CONST
查詢條件一般是 索引列 = 具體常量值
EQ_REF
一般是在多表關聯查詢時做爲鏈接條件使用.<u>字段 possible_keys(候選索引)</u>
<u>字段 key(實際使用的索引)</u>
若是是合併索引(INDEX_MERGE), 則此處可能存在超過1個的key
<u>字段 key_len(使用索引的實際長度)</u>
該字段能夠評估組合索引是否徹底被使用或僅僅是最左前綴被用到.
該字段顯示的值爲索引字段的最大可能長度, 並不是實際使用長度.(即 key_len 是根據表定義計算, 而非表內檢索)
計算規則
字段類型 | 計算方式 | |
---|---|---|
字符串 | char(n) | n字節長度 |
varchar(n) | 如果utf8編碼, 則是 n3 + 2 字節 若是是 utf8mb4 編碼, 則是 4 n + 2 字節. |
|
數值 | tinyint | 1字節 |
smallint | 2字節 | |
mediumint | 3字節 | |
int | 4字節 | |
bigint | 8字節 | |
時間 | date | 3字節 |
timestamp | 4字節 | |
datetime | 8字節 |
若是對應索引字段容許爲 null, 則還要額外消耗1個字節來存儲 NULL.
<u>字段 ref</u>
表示索引的查找條件, 多是常量(const) 或 聯合查詢中另外一張表的某個字段.
<u>字段 row(掃描行數)</u>
估算的須要掃描的行數, 注意是估算的.
在某些狀況下若索引統計信息誤差較大, 則此處的預估掃描行數也會過大, 致使影響查詢計劃的選擇.
可使用 SHOW INDEX FROM 表名
來查看索引統計信息
可使用 ANYLYSIS TABLE 表名
來從新統計索引信息.
<u>字段 filtered</u>
<u>字段 Extra(額外信息)</u>
該列包含MySQL解決查詢的詳細信息
值 | 說明 |
---|---|
Using filesort | mysql沒法依靠索引直接獲取有序記錄, 而是對結果進行額外排序. mysql有兩種文件排序算法,這兩種排序方式均可以在內存或者磁盤上完成 explain不會告訴你mysql將使用哪種文件排序 也不會告訴你排序會在內存裏仍是磁盤上完成。 |
Using index | 使用覆蓋索引,以免訪問表。不要把覆蓋索引和index訪問類型弄混了。 |
Using index condition | 索引下推優化, 5.6新增特性 |
Using temporary | 意味着mysql在對查詢結果排序時會使用一個臨時表 |
Using where | 使用了 where 過濾 這意味着mysql服務器將在存儲引擎檢索行後再進行過濾 許多where條件裏涉及索引中的列,當(而且若是)它讀取索引時,就能被存儲引擎檢驗 所以不是全部帶where子句的查詢都會顯示「Using where」。 有時「Using where」的出現就是一個暗示:查詢可受益於不一樣的索引。 |
Range checked for each record(index map: N) | 這個意味着沒有好用的索引,新的索引將在聯接的每一行上從新估算,N是顯示在possible_keys列中索引的位圖,而且是冗餘的。 |
using join buffer | 在表聯結時, 使用了鏈接緩存 |
寫在最前: SHOW PROFILE 命令將被棄用, 注意, 僅僅是
SHOW PROFILE
命令棄用.替代方案是從 information_schema 中的profiling數據表進行查看, 可參數連接:
查看語句執行的時間在各個步驟的開銷
show profile 分析SQL性能工具(檢測數據存在於臨時表中)
SET profiling=1;
查看profile的資源開銷結果
show profiles
查看全部的分析結果(會有一個數量上限)show profile
查看最後一條執行語句的分析結果show profile for query <id>
查看指定執行語句的詳細分析結果show profile cpu, block io for query <id>
查看詳細信息, 且包含 cpu, block.io 執行時間這一部分更詳細的能夠參考如:
待用到時補充.