| name | mysql-slow-query-diagnose |
| version | 1.0.0 |
| description | Slow query diagnosis with root cause analysis and index optimization recommendations. Identifies TOP N slow queries, analyzes scan efficiency, calculates index hit rate, and suggests covering indexes โ turning a 20-minute manual diagnosis into 8 seconds.
|
| allowed-tools | db_query, db_get_slow_log, db_describe_table, db_get_status |
MySQL Slow Query Diagnose (Diagnosis + Optimization)
Overview
Slow queries are the #1 cause of database performance degradation. This skill goes beyond simply listing slow queries โ it performs root cause analysis for each one: how many rows scanned vs returned, which index was used (or missed), and what index to add to fix it.
Key capabilities:
- Identify TOP N slow queries by execution time, lock time, or scan rows
- Calculate index hit rate (rows_examined / rows_sent) โ the key metric for query efficiency
- Analyze EXPLAIN plans to identify full table scans, filesort, temporary tables
- Suggest covering indexes with estimated improvement
- Output a prioritized action list sorted by impact
Real-world result: A DBA team reduced average slow query resolution from 20 minutes to 8.3 seconds โ 144x improvement โ by having AI perform the diagnosis automatically.
When to Use
Apply this skill when:
- Database response time suddenly increases
- Application reports query timeouts
- Monitoring shows slow query count spike
- Periodic performance review / health check
- After schema changes to verify query performance
- Developer asks "why is this query slow?"
Required MCP Server
| Tool | Purpose | Example |
|---|
db_query | Run diagnostics and EXPLAIN | db_query("EXPLAIN SELECT ...") |
db_get_slow_log | Retrieve slow query entries | db_get_slow_log(hours=1, limit=20) |
db_describe_table | Check table indexes | db_describe_table("orders") |
db_get_status | Get performance counters | db_get_status("Slow_queries") |
Required MySQL Privileges
SELECT on mysql.slow_log or performance_schema.events_statements_summary_by_digest
PROCESS โ for EXPLAIN on other sessions' queries
Diagnostic Workflow
Step 1: Collect Slow Queries
SELECT
DIGEST_TEXT AS sql_template,
COUNT_STAR AS exec_count,
ROUND(SUM_TIMER_WAIT / 1000000000000, 3) AS total_time_sec,
ROUND(AVG_TIMER_WAIT / 1000000000000, 3) AS avg_time_sec,
ROUND(MAX_TIMER_WAIT / 1000000000000, 3) AS max_time_sec,
ROUND(SUM_ROWS_EXAMINED / COUNT_STAR, 0) AS avg_rows_examined,
ROUND(SUM_ROWS_SENT / COUNT_STAR, 0) AS avg_rows_sent,
SUM_NO_INDEX_USED AS no_index_count
FROM performance_schema.events_statements_summary_by_digest
WHERE DIGEST_TEXT IS NOT NULL
AND SUM_TIMER_WAIT > 0
ORDER BY SUM_TIMER_WAIT DESC
LIMIT 20;
SELECT
start_time,
user_host,
query_time,
lock_time,
rows_sent,
rows_examined,
LEFT(sql_text, 300) AS sql_fragment
FROM mysql.slow_log
WHERE start_time > DATE_SUB(NOW(), INTERVAL 1 HOUR)
ORDER BY query_time DESC
LIMIT 20;
Also check overall slow query status:
SHOW GLOBAL STATUS LIKE 'Slow_queries';
SHOW GLOBAL STATUS LIKE 'Slow_launch_threads';
SHOW VARIABLES LIKE 'long_query_time';
SHOW VARIABLES LIKE 'slow_query_log';
Step 2: Analyze Each Top Query
For each slow query identified, run:
EXPLAIN FORMAT=JSON {the_query};
SHOW INDEX FROM {table_name};
SELECT
TABLE_NAME,
TABLE_ROWS,
ROUND(DATA_LENGTH / 1024 / 1024, 2) AS data_mb,
ROUND(INDEX_LENGTH / 1024 / 1024, 2) AS index_mb
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = '{db}' AND TABLE_NAME = '{table}';
Step 3: Calculate Efficiency Metrics
For each query, compute:
| Metric | Formula | Interpretation |
|---|
| Index Hit Rate | rows_sent / rows_examined ร 100% | <1% = severe index miss |
| Scan Efficiency | rows_examined / table_rows | >50% = nearly full scan |
| Lock Ratio | lock_time / query_time ร 100% | >30% = lock contention |
| Exec Frequency | COUNT_STAR from digest | High + slow = critical |
Classification:
IF index_hit_rate < 1% AND no_index_used:
โ Type: MISSING_INDEX (Critical)
โ Action: Add index
ELSE IF scan_efficiency > 50%:
โ Type: FULL_SCAN (High)
โ Action: Optimize query or add covering index
ELSE IF lock_ratio > 30%:
โ Type: LOCK_CONTENTION (Medium)
โ Action: Check concurrent transactions
ELSE IF avg_time > threshold:
โ Type: DATA_VOLUME (Medium)
โ Action: Archive or partition
Step 4: Generate Index Recommendations
For each missing index case, suggest:
ALTER TABLE orders ADD INDEX idx_status_createtime (status, create_time);
Index design rules:
- Equality first โ columns with
= condition go first in composite index
- Range last โ columns with
>, <, BETWEEN go last
- Covering index โ if possible, include all SELECT columns to avoid table lookup
- Order matters โ
(status, create_time) โ (create_time, status)
Output Templates
Initial Report
๐ MySQL Slow Query Diagnostic Report
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ Instance: {host}:{port}
Analysis Period: Last {hours} hours
Slow Query Threshold: {threshold}s
Total Slow Queries: {count}
๐ด TOP {N} Slow Queries (by total impact)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
TOP 1 โก Total Impact: {total_time}s across {count} executions
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ SQL: {sql_template} โ
โ Avg Time: {avg}s | Max: {max}s โ
โ Rows Examined: {examined} | Returned: {sent}โ
โ Index Hit Rate: {rate}% ๐ด MISSING INDEX โ
โ โ
โ Root Cause: Full table scan on {table} โ
โ โ No index on ({columns}) โ
โ โ
โ โ
Recommended: โ
โ ALTER TABLE {table} ADD INDEX โ
โ idx_{name} ({columns}); โ
โ Expected: {current}s โ <0.1s โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
TOP 2 โก ...
TOP 3 โก ...
๐ Summary
| Rank | SQL Pattern | Executions | Avg Time | Hit Rate | Fix |
|------|------------|------------|----------|----------|-----|
| 1 | {pattern} | {count} | {time}s | {rate}% | Add index |
| 2 | ... | ... | ... | ... | ... |
โก Priority Actions
1. [Critical] Add index on {table}({cols}) โ fixes TOP 1, est. 300x speedup
2. [High] Add index on {table}({cols}) โ fixes TOP 2
3. [Medium] Schedule batch query for off-peak โ TOP 3 is legitimate report
After Index Applied (Follow-up)
โ
Index Verification
โโโโโโโโโโโโโโโโโโ
Query: {sql_template}
Before: avg {old}s, examined {old_rows} rows
After: avg {new}s, examined {new_rows} rows
Improvement: {factor}x faster ๐
Example Usage
User: "Check slow queries on db-prod-01, last 1 hour"
AI Response:
I'll analyze slow queries from the last hour.
๐ MySQL Slow Query Diagnostic Report
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ Instance: db-prod-01:3306
Analysis Period: Last 1 hour
Total Slow Queries: 62
๐ด TOP 3 Slow Queries
TOP 1 โก 23.7s avg ร 47 executions = 1,114s total impact
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ SELECT * FROM order_detail โ
โ WHERE create_time > ? AND status = ? โ
โ โ
โ Avg Time: 23.7s | Max: 45.2s โ
โ Rows Examined: 12,800,000 | Returned: 380 โ
โ Index Hit Rate: 0.003% ๐ด โ
โ โ
โ Root Cause: Full table scan โ no index on โ
โ (status, create_time) โ
โ โ
โ โ
Fix: ALTER TABLE order_detail ADD INDEX โ
โ idx_status_createtime (status, create_time)โ
โ Expected: 23.7s โ <0.1s (237x faster) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
TOP 2 โก 8.4s avg ร 12 executions = 100.8s total impact
โ Full scan on user_order (5.6M rows)
โ Fix: ADD INDEX (merchant_id)
TOP 3 โก 4.2s avg ร 3 executions = 12.6s total impact
โ Index hit, batch report โ schedule off-peak
โก Priority Actions:
1. [Critical] Add (status, create_time) on order_detail
2. [High] Add (merchant_id) on user_order
3. [Info] Schedule TOP 3 report query to 02:00-05:00
Best Practices
Index Design Checklist
When NOT to Add an Index
- Query runs infrequently (batch job once a day)
- Table is small (< 10,000 rows) โ full scan may be faster
- Write-heavy table โ each index adds write overhead
- Query already uses a good index but returns many rows (data volume issue)
Common Anti-Patterns
| Anti-Pattern | Why It's Bad | Fix |
|---|
SELECT * with index | Can't use covering index | Select only needed columns |
LIKE '%keyword%' | Leading wildcard can't use index | Use full-text search or LIKE 'keyword%' |
OR conditions | May cause index merge | Rewrite as UNION ALL or use composite index |
Function on indexed column WHERE YEAR(dt)=2024 | Index not used | Use range: WHERE dt >= '2024-01-01' |
Quick Reference
| Action | Query |
|---|
| Top slow queries (perf_schema) | SELECT ... FROM events_statements_summary_by_digest ORDER BY SUM_TIMER_WAIT DESC |
| Top slow queries (slow_log) | SELECT ... FROM mysql.slow_log WHERE start_time > ... ORDER BY query_time DESC |
| EXPLAIN a query | EXPLAIN FORMAT=JSON SELECT ... |
| Show table indexes | SHOW INDEX FROM table_name |
| Table size | SELECT ... FROM information_schema.TABLES WHERE TABLE_NAME='...' |
| Check slow query log status | SHOW VARIABLES LIKE 'slow_query_log' |
| Enable slow query log | SET GLOBAL slow_query_log = ON |
Use this skill for intelligent slow query diagnosis โ not just listing queries, but explaining WHY they're slow and HOW to fix them.