MySQL 使用explain分析sql语句示例_sql

EXPLAIN SELECT * 
FROM t_user u, user_role ur 
WHERE u.id = ur.user_id;

🧩 一、分析表格内容

列名

含义

id

执行顺序标识,1 表示同一级别的查询

select_type

查询类型,这里都是 SIMPLE(简单查询)

table

当前执行的表:ur(user_role) 和 u(t_user)

type

连接类型

possible_keys

可能使用的索引

key

实际使用的索引

key_len

实际使用的索引长度(字节)

ref

哪个字段或常量与索引比较

rows

预估扫描的行数

Extra

额外信息(是否 Using where / index / temporary 等)


🧠 二、执行顺序与含义

第一行(表 ur = user_role)



type

ALL

possible_keys

fk_ur_user_id

key

NULL

key_len

NULL

Extra

Using where

说明:

  • MySQL 对 user_role 表做了全表扫描(ALL)
  • 虽然它有一个可能的索引 fk_ur_user_id(即 user_id 上的索引),但没有被使用;
  • key_len = NULL 表示没用到索引
  • Using where 表示通过条件过滤。

🔍 原因可能是:
优化器认为扫描整个表 + 关联比使用索引更快,或者 user_role.user_id 上的索引选择性不高(重复值太多)。


第二行(表 u = t_user)



type

eq_ref

key

PRIMARY

key_len

98

ref

test.ur.user_id

说明:

  • type=eq_ref:最优的连接方式之一(主键等值连接),表示对 t_user 每次查一条。
  • key=PRIMARY:使用了主键索引;
  • key_len=98:主键长度为 98 字节;
  • ref=test.ur.user_id:表示关联条件是 u.id = ur.user_id
  • 表示 MySQL 对 ur 表的每一行,根据 user_idt_user 查主键(点查)。

📏 三、key_len=98 的解释

这说明 t_user.id 主键占用了 98 个字节
这通常发生在以下情况之一:

  1. id 是一个 VARCHAR(36)(比如 UUID 字符串),在 utf8mb4 下每字符最多占 4 字节:
    36 × 3(或4) ≈ 108 ~ 144 字节,所以 98 是合理的近似。
  2. 或者 id 是较长的字符串类型(非 INT / BIGINT)。

建议:
如果这个字段只是用来做主键关联,而不是业务展示,可以考虑改为:

id BIGINT UNSIGNED AUTO_INCREMENT

id BINARY(16)  -- 存储 UUID 更紧凑

这样索引长度可以从 98 字节降到 8 或 16 字节,性能更好。


⚙️ 四、优化建议

  1. 确认 user_role.user_id 上是否有索引
  • 如果没有,添加索引:
CREATE INDEX idx_user_role_user_id ON user_role(user_id);
  • 如果已有但没被使用,可能是统计信息不准,可以尝试:
ANALYZE TABLE user_role;
  1. 检查主键类型
  • 若主键为 VARCHAR,建议改成整数型或 BINARY。
  1. 验证优化器决策
  • 加上 STRAIGHT_JOIN 强制连接顺序,看看是否更优:
EXPLAIN SELECT STRAIGHT_JOIN * 
FROM user_role ur, t_user u 
WHERE u.id = ur.user_id;

✅ 总结


是否用索引

key_len

说明

user_role

❌ 没用

NULL

全表扫描

t_user

✅ 用了主键索引

98

每次通过主键等值查一条

key_len=98 不代表好坏,只是说明用了一个比较“长”的索引字段。