10個你必須掌握的頂級MySQL分析技巧
概述
介紹10種MySQL高級性能分析和優(yōu)化的SQL語句,幫助DBA和開發(fā)人員定位性能瓶頸、優(yōu)化查詢效率。
1. 找出執(zhí)行最慢的查詢
需求
定位慢查詢?nèi)罩局凶詈臅r的SQL,分析是否需要優(yōu)化索引或重構(gòu)查詢。
步驟
開啟慢查詢?nèi)罩?/p>
設(shè)置慢查詢閾值
查詢慢查詢?nèi)罩净?code>slow_log表
代碼
-- 1. 開啟慢查詢記錄
SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 1; -- 超過1秒記錄
SET GLOBAL log_queries_not_using_indexes = ON;
-- 2. 從performance_schema獲取慢查詢(MySQL 5.6+)
SELECT
DIGEST_TEXT AS query_sample,
COUNT_STAR AS exec_count,
SUM_TIMER_WAIT / 1000000000 AS total_secs,
AVG_TIMER_WAIT / 1000000000 AS avg_secs,
MAX_TIMER_WAIT / 1000000000 AS max_secs
FROM performance_schema.events_statements_summary_by_digest
ORDER BY SUM_TIMER_WAIT DESC
LIMIT 10;
2. 查找未使用索引的查詢
需求
找出全表掃描或未合理使用索引的SQL。
步驟
開啟log_queries_not_using_indexes
查詢慢日志或使用EXPLAIN分析
代碼
-- 開啟記錄未使用索引的查詢
SET GLOBAL log_queries_not_using_indexes = ON;
-- 通過performance_schema查找未使用索引的查詢
SELECT
DIGEST_TEXT,
COUNT_STAR,
SUM_NO_INDEX_USED,
SUM_NO_GOOD_INDEX_USED
FROM performance_schema.events_statements_summary_by_digest
WHERE SUM_NO_INDEX_USED > 0 OR SUM_NO_GOOD_INDEX_USED > 0
ORDER BY COUNT_STAR DESC;
3. 分析鎖等待情況
需求
定位當前阻塞的事務和鎖等待鏈。
步驟
查詢information_schema中的鎖相關(guān)表
分析事務等待關(guān)系
代碼
-- 查看當前鎖等待(MySQL 8.0)
SELECT
r.trx_id AS waiting_trx_id,
r.trx_mysql_thread_id AS waiting_thread,
r.trx_query AS waiting_query,
b.trx_id AS blocking_trx_id,
b.trx_mysql_thread_id AS blocking_thread,
b.trx_query AS blocking_query
FROM information_schema.innodb_lock_waits w
JOIN information_schema.innodb_trx r ON w.requesting_trx_id = r.trx_id
JOIN information_schema.innodb_trx b ON w.blocking_trx_id = b.trx_id;
-- MySQL 8.0 推薦使用 performance_schema
SELECT
waiting_pid,
waiting_query,
blocking_pid,
blocking_query
FROM sys.innodb_lock_waits;
4. 監(jiān)控臨時表使用情況
需求
發(fā)現(xiàn)創(chuàng)建了大量磁盤臨時表的查詢(性能殺手)。
代碼
-- 查看臨時表使用統(tǒng)計
SELECT
DIGEST_TEXT,
COUNT_STAR,
SUM_CREATED_TMP_TABLES,
SUM_CREATED_TMP_DISK_TABLES,
ROUND(SUM_CREATED_TMP_DISK_TABLES / SUM_CREATED_TMP_TABLES * 100, 2) AS disk_tmp_ratio
FROM performance_schema.events_statements_summary_by_digest
WHERE SUM_CREATED_TMP_TABLES > 0
ORDER BY SUM_CREATED_TMP_DISK_TABLES DESC
LIMIT 10;
5. 分析索引使用效率
需求
找出冗余索引、未使用索引和重復索引。
代碼
-- 查找未使用的索引(從sys庫)
SELECT
table_schema,
table_name,
index_name,
rows_selected,
rows_inserted,
rows_updated,
rows_deleted
FROM sys.schema_unused_indexes;
-- 查找重復索引
SELECT
table_schema,
table_name,
redundant_index_name,
dominant_index_name
FROM sys.schema_redundant_indexes;
6. 查看表和索引的碎片率
需求
識別高碎片率的表,決定是否需要優(yōu)化表。
代碼
-- 查看表碎片情況
SELECT
table_schema,
table_name,
ROUND(data_length / 1024 / 1024, 2) AS data_mb,
ROUND(index_length / 1024 / 1024, 2) AS index_mb,
ROUND(data_free / 1024 / 1024, 2) AS free_mb,
ROUND(data_free / (data_length + index_length) * 100, 2) AS fragmentation_ratio
FROM information_schema.tables
WHERE table_schema NOT IN ('mysql', 'information_schema', 'performance_schema')
AND data_free > 0
ORDER BY fragmentation_ratio DESC;
7. 監(jiān)控InnoDB緩沖池命中率
需求
評估內(nèi)存是否充足,是否需要增加innodb_buffer_pool_size。
代碼
-- 查看Buffer Pool命中率
SELECT
(SELECT VARIABLE_VALUE
FROM performance_schema.global_status
WHERE VARIABLE_NAME = 'Innodb_buffer_pool_read_requests') AS read_requests,
(SELECT VARIABLE_VALUE
FROM performance_schema.global_status
WHERE VARIABLE_NAME = 'Innodb_buffer_pool_reads') AS physical_reads,
ROUND((1 - (SELECT VARIABLE_VALUE
FROM performance_schema.global_status
WHERE VARIABLE_NAME = 'Innodb_buffer_pool_reads') /
(SELECT VARIABLE_VALUE
FROM performance_schema.global_status
WHERE VARIABLE_NAME = 'Innodb_buffer_pool_read_requests')) * 100, 2) AS hit_rate;
8. 查找排序操作過多的查詢
需求
識別需要大量磁盤排序的查詢(filesort)。
代碼
-- 查找高排序量的查詢
SELECT
DIGEST_TEXT,
COUNT_STAR AS exec_count,
SUM_SORT_ROWS AS total_sorted_rows,
AVG_SORT_ROWS AS avg_sorted_rows,
SUM_SORT_MERGE_PASSES AS merge_passes
FROM performance_schema.events_statements_summary_by_digest
WHERE SUM_SORT_ROWS > 100000
ORDER BY SUM_SORT_ROWS DESC
LIMIT 10;
9. 監(jiān)控連接數(shù)和線程運行情況
需求
檢測連接池是否合理,是否有連接泄漏或高并發(fā)問題。
代碼
-- 查看當前連接狀態(tài)
SELECT
command,
COUNT(*) AS count,
ROUND(COUNT(*) / (SELECT COUNT(*) FROM information_schema.processlist) * 100, 2) AS percentage
FROM information_schema.processlist
GROUP BY command;
-- 查看歷史連接統(tǒng)計
SHOW STATUS LIKE 'Threads_%';
SHOW STATUS LIKE 'Max_used_connections';
-- 檢查是否超過max_connections閾值
SELECT
@@max_connections AS max_conn,
(SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME = 'Max_used_connections') AS max_used,
ROUND((SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME = 'Max_used_connections') / @@max_connections * 100, 2) AS usage_pct;
10. 分析表連接(JOIN)效率
需求
找出多表JOIN時驅(qū)動表選擇不當或缺少關(guān)聯(lián)索引的問題。
代碼
-- 從歷史統(tǒng)計中找高成本JOIN查詢
SELECT
DIGEST_TEXT,
COUNT_STAR,
SUM_ROWS_EXAMINED AS total_rows_examined,
SUM_ROWS_SENT AS total_rows_sent,
ROUND(SUM_ROWS_EXAMINED / SUM_ROWS_SENT, 2) AS rows_examined_per_row_sent,
SUM_TIMER_WAIT / 1000000000 AS total_secs
FROM performance_schema.events_statements_summary_by_digest
WHERE DIGEST_TEXT LIKE '%JOIN%'
AND SUM_ROWS_EXAMINED / NULLIF(SUM_ROWS_SENT, 0) > 1000 -- 掃描行數(shù)/返回行數(shù)比例過高
ORDER BY rows_examined_per_row_sent DESC
LIMIT 10;
詳細總結(jié)
性能優(yōu)化的核心思路
| 優(yōu)化維度 | 關(guān)鍵指標 | 建議閾值 |
|---|---|---|
| 慢查詢 | 查詢時間 > 1秒 | 優(yōu)化索引或改寫SQL |
| 索引使用 | 全表掃描次數(shù) | 大表必須走索引 |
| 鎖等待 | 等待時間 > 5秒 | 縮短事務,降低隔離級別 |
| 臨時表 | 磁盤臨時表比例 > 10% | 增加tmp_table_size,優(yōu)化GROUP BY/ORDER BY |
| 碎片率 | 碎片率 > 20% | 執(zhí)行OPTIMIZE TABLE |
| Buffer Pool命中率 | < 95% | 增加內(nèi)存或優(yōu)化查詢 |
| 磁盤排序 | 每查詢排序行 > 1000 | 添加復合索引覆蓋排序字段 |
| 連接數(shù) | 使用率 > 80% | 增加連接池或max_connections |
| JOIN效率 | 掃描/返回比例 > 1000 | 檢查驅(qū)動表和關(guān)聯(lián)索引 |
日常巡檢建議
-- 創(chuàng)建每日性能檢查的存儲過程示例
DELIMITER $$
CREATE PROCEDURE daily_performance_check()
BEGIN
-- 1. 檢查top10慢查詢
SELECT 'Top 10 Slow Queries' AS check_item;
CALL top_slow_queries();
-- 2. 檢查高碎片表
SELECT 'High Fragmentation Tables' AS check_item;
CALL check_fragmentation();
-- 3. 檢查未使用索引
SELECT 'Unused Indexes' AS check_item;
CALL check_unused_indexes();
-- 4. 檢查鎖等待
SELECT 'Lock Waits' AS check_item;
CALL check_lock_waits();
END$$
DELIMITER ;
最佳實踐
1.定期收集統(tǒng)計信息
ANALYZE TABLE your_table;
2.定期清理慢查詢?nèi)罩?/strong>,避免磁盤占滿
3.使用監(jiān)控工具(Prometheus + Grafana)采集performance_schema指標
4.設(shè)置告警閾值:
- 慢查詢數(shù)量 > 100/小時
- Buffer Pool命中率 < 99%(生產(chǎn)環(huán)境)
- 鎖超時次數(shù) > 10/小時
5.版本差異注意:
- MySQL 5.6-5.7:
performance_schema需要手動開啟 - MySQL 8.0:默認開啟,
sys庫非常實用 - 推薦升級到8.0+獲得更好的性能洞察能力
通過這10種SQL分析方法,可以系統(tǒng)性地定位MySQL性能問題,從慢查詢、索引、鎖、內(nèi)存、磁盤IO等多個維度進行優(yōu)化,顯著提升數(shù)據(jù)庫響應速度和吞吐量。
到此這篇關(guān)于10個你必須掌握的頂級MySQL分析技巧的文章就介紹到這了,更多相關(guān)MySQL分析技巧內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
mysql 8.0.22壓縮包完整安裝與配置教程圖解(親測安裝有效)
這篇文章主要介紹了mysql 8.0.22壓縮包完整安裝與配置教程圖解(親測安裝有效),本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12
MYSQL必知必會讀書筆記第十和十一章之使用函數(shù)處理數(shù)據(jù)
這篇文章主要介紹了MYSQL必知必會讀書筆記第十和十一章之使用函數(shù)處理數(shù)據(jù)的相關(guān)資料,需要的朋友可以參考下2016-05-05
Jmeter如何向數(shù)據(jù)庫批量插入數(shù)據(jù)
這篇文章主要介紹了Jmeter如何向數(shù)據(jù)庫批量插入數(shù)據(jù)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-03-03
MySQL中Binary Log二進制日志文件的基本操作命令小結(jié)
這篇文章主要介紹了MySQL中Binary Log二進制日志文件的基本操作小結(jié),包括利用二進制日志恢復數(shù)據(jù)的方法,需要的朋友可以參考下2015-12-12
mysql數(shù)據(jù)庫SQL子查詢(史上最詳細)
這篇文章主要給大家介紹了關(guān)于mysql數(shù)據(jù)庫SQL子查詢的相關(guān)資料,子查詢指的是嵌套在某個語句中的SELECT語句, MySQL支持標準SQL所要求的所有子查詢形式和操作,此外還進行了一些擴展,需要的朋友可以參考下2024-05-05

