Transformers are Inherently Succinct——Transformer 天生简洁
2026/7/17 20:16:43
在数据库性能调优中,EXPLAIN是MySQL提供的核心工具之一。它通过解析SQL语句的执行计划,帮助开发者直观理解查询如何访问数据、是否使用索引、是否存在潜在性能瓶颈。本文将结合真实案例与官方文档,系统讲解EXPLAIN的使用方法及优化策略。
EXPLAIN通过模拟查询优化器的决策过程,输出以下关键信息:
典型场景:某电商系统查询商品列表时响应缓慢,通过EXPLAIN发现查询使用了ALL类型扫描,扫描行数达百万级。优化后通过添加复合索引,扫描行数降至千级,响应时间从3秒降至0.02秒。
EXPLAINSELECTu.name,o.order_dateFROMusers uJOINorders oONu.id=o.user_idWHEREu.status='active'ANDo.amount>100;输出结果示例:
| id | select_type | table | type | possible_keys | key | rows | Extra |
|---|---|---|---|---|---|---|---|
| 1 | SIMPLE | u | ref | idx_status | idx_status | 1000 | Using where |
| 1 | SIMPLE | o | ref | idx_user_id | idx_user_id | 50 | Using index condition |
type列(访问类型,性能从高到低):
system>const>eq_ref>ref>range>index>ALLtype=range表示使用索引范围查询(如BETWEEN、>),而type=ALL表示全表扫描key列:
NULL表示未使用索引possible_keys显示有3个候选索引,但key为NULL,说明索引选择策略失效Extra列(需重点优化):
Using index:覆盖索引,无需回表(最佳情况)Using filesort:需额外排序,可能引发性能问题Using temporary:使用临时表,常见于GROUP BY问题SQL:
SELECT*FROMproductsWHEREnameLIKE'%手机%';EXPLAIN结果:
type: ALL, key: NULL, Extra: Using where优化方案:
%开头),改用name LIKE '手机%'原始SQL:
SELECTuser_id,order_dateFROMordersWHEREuser_id=1001;优化前:
PRIMARY KEY (id)Using index)优化后:
ALTER TABLE orders ADD INDEX idx_user_date (user_id, order_date);type: ref, key: idx_user_date, Extra: Using index问题SQL:
SELECTu.name,o.amountFROMusers uLEFTJOINorders oONu.id=o.user_idWHEREo.amount>500;EXPLAIN问题:
LEFT JOIN导致优化器无法使用o.amount索引过滤优化方案:
INNER JOIN(若业务允许)SELECTu.name,o.amountFROMorders oINNERJOINusers uONo.user_id=u.idWHEREo.amount>500;EXPLAIN FORMAT=JSON获取更详细的执行计划信息,包括成本估算、循环次数等:
EXPLAINFORMAT=JSONSELECT*FROMlarge_tableWHEREcategory='A';输出示例:
{"query_block":{"select_id":1,"cost_info":{"query_cost":"1234.56"},"table":{"table_name":"large_table","access_type":"ref","key":"idx_category","rows_examined_per_scan":1000,"filtered":10.00}}}结合slow_query_log定位问题SQL:
-- 开启慢查询日志SETGLOBALslow_query_log='ON';SETGLOBALlong_query_time=2;-- 设置阈值(秒)-- 分析工具示例(使用mysqldumpslow)mysqldumpslow-s t/var/log/mysql/mysql-slow.log当Extra显示Using index condition时,表示优化器将WHERE条件过滤下推到存储引擎层,减少回表次数。例如:
-- 假设orders表有(user_id, status)复合索引EXPLAINSELECT*FROMordersWHEREuser_id=1001ANDstatus='paid';输出可能显示:
type: ref, key: idx_user_status, Extra: Using index condition索引并非越多越好:
避免过度优化:
FORCE INDEX需谨慎,可能适得其反定期更新统计信息:
ANALYZETABLElarge_table;-- 更新表统计信息监控索引使用率:
SELECT*FROMperformance_schema.table_io_waits_summary_by_index_usage;通过EXPLAIN分析SQL执行计划是数据库优化的核心技能。开发者应重点关注:
建议建立优化流程:
掌握这些技巧后,开发者可系统化解决80%以上的数据库性能问题,显著提升系统吞吐量与响应速度。