慢查询优化:EXPLAIN执行计划分析

孙前端

· 阅读 1061

分享
慢查询优化

慢查询优化:EXPLAIN执行计划分析

慢查询是数据库性能问题的根源。优化慢SQL的第一步是使用EXPLAIN分析执行计划,理解MySQL是如何执行这条SQL的。本文通过几个实际案例,讲解EXPLAIN输出中每个字段的含义和优化思路。

EXPLAIN输出解读

id:查询的序号。相同id的执行顺序从上到下。子查询的id递增。

select_type:查询类型。SIMPLE(简单查询)、PRIMARY(外层查询)、SUBQUERY(子查询)、DERIVED(派生表/FROM子查询)。

type:访问类型,性能从好到差:system > const > eq_ref > ref > range > index > ALL。看到ALL说明全表扫描,必须优化。目标是至少达到range级别。

key:实际使用的索引。NULL说明没有使用索引。

rows:预估扫描的行数。这个数字越小越好。

Extra:额外信息。Using index(覆盖索引,好)、Using filesort(需要额外排序,需优化)、Using temporary(使用临时表,需优化)。

案例一:隐式类型转换导致索引失效

SQL:SELECT * FROM users WHERE phone = 13800138000。phone字段是VARCHAR类型,但查询条件用了数字。MySQL做了隐式类型转换,导致索引失效。修复:将查询条件改为字符串 '13800138000'。优化后扫描行数从500万降到1。

案例二:联合索引顺序不当

SQL:SELECT * FROM orders WHERE status = 'paid' AND create_time > '2024-01-01'。原索引 (create_time, status),EXPLAIN显示只用了create_time的range扫描,status没有用到。修复:调整索引为 (status, create_time),因为status是等值查询,放前面可以精确定位,create_time做范围扫描。

案例三:文件排序优化

SQL:SELECT * FROM articles WHERE category_id = 5 ORDER BY create_time DESC LIMIT 20。Extra显示Using filesort。修复:创建联合索引 (category_id, create_time),MySQL可以直接按索引顺序读取,消除filesort。

优化方法论

1. 先EXPLAIN看执行计划,定位问题(全表扫描?文件排序?临时表?)2. 检查索引是否合理(字段顺序、是否覆盖)3. 检查是否有索引失效的情况(函数、类型转换、OR条件)4. 考虑SQL改写(子查询改JOIN、避免SELECT *)5. 最后才考虑加索引(索引不是万能的)。