redis eval表达式
MySQL 中
EXPLAIN 的 type 字段表示 表的访问方式(Access Type),它反映了 SQL 查询扫描数据的效率,是判断 SQL 性能最重要的指标之一。一般来说:
性能最好
↓
system
const
eq_ref
ref
fulltext
ref_or_null
index_merge
unique_subquery
index_subquery
range
index
ALL
↑
性能最差
其中,面试和工作中最需要掌握的是:
system
const
eq_ref
ref
range
index
ALL
1. ALL(全表扫描)
最差。
MySQL 需要扫描整张表。
例如:
CREATE TABLE user (
id BIGINT PRIMARY KEY,
name VARCHAR(50),
age INT,
INDEX idx_age(age)
);
执行:
EXPLAIN
SELECT * FROM user WHERE name = 'Tom';
结果:
| type |
|---|
| ALL |
原因:
name 没有索引
执行过程:
第一行:判断 name='Tom'
第二行:判断 name='Tom'
第三行:判断 name='Tom'
……
扫描整张表
2. index(全索引扫描)
比 ALL 稍微好一点。
扫描整个索引树,而不是整张表。
例如:
EXPLAIN
SELECT age FROM user;
结果:
| type |
|---|
| index |
因为:
查询的字段 age 正好在索引中
执行过程:
从索引头开始
↓
一直扫到索引尾
虽然仍然是全扫描,但:
索引比数据页小
IO 更少
3. range(范围扫描)
非常常见。
例如:
EXPLAIN
SELECT * FROM user WHERE age > 20;
结果:
| type |
|---|
| range |
适用于:
BETWEEN
>
<
>=
<=
IN
LIKE 'abc%'
例如:
WHERE age BETWEEN 20 AND 30
WHERE id IN (1,2,3)
WHERE name LIKE 'Tom%'
执行过程:
找到范围起点
↓
顺着 B+ 树扫描
↓
直到范围结束
4. ref(非唯一索引等值查询)
比较好。
例如:
CREATE INDEX idx_age ON user(age);
执行:
EXPLAIN
SELECT * FROM user WHERE age = 20;
结果:
| type |
|---|
| ref |
原因:
age 有普通索引
但 age 不是唯一的
执行过程:
定位 age=20
↓
拿到所有 age=20 的主键
↓
回表
例如:
20 → 3条记录
5. eq_ref(唯一索引关联)
非常好。
通常出现在:
JOIN
例如:
SELECT *
FROM orders o
JOIN user u
ON o.user_id = u.id;
其中:
u.id 为主键
结果:
| type |
|---|
| eq_ref |
含义:
每次关联只匹配一条记录
例如:
订单用户ID=1
↓
用户表主键查询
↓
唯一一条
6. const(主键或唯一索引等值查询)
性能极好。
例如:
EXPLAIN
SELECT *
FROM user
WHERE id = 1;
结果:
| type |
|---|
| const |
原因:
id 是主键
或者:
WHERE email='xxx'
其中:
email UNIQUE
执行过程:
查询优化阶段
↓
直接确定结果
最多返回:
1条记录
7. system
最好。
实际上是 const 的特殊情况。
表只有:
0条
或
1条
例如:
CREATE TABLE config(
version INT
);
表中只有:
1条记录
执行:
EXPLAIN
SELECT * FROM config;
结果:
| type |
|---|
| system |
几乎见不到。
举个完整例子
假设:
CREATE TABLE user(
id BIGINT PRIMARY KEY,
email VARCHAR(50) UNIQUE,
age INT,
name VARCHAR(50),
INDEX idx_age(age)
);
1.
SELECT * FROM user WHERE id=1;
type = const
2.
SELECT * FROM user WHERE email='a@qq.com';
type = const
3.
SELECT * FROM user WHERE age=20;
type = ref
4.
SELECT * FROM user WHERE age>20;
type = range
5.
SELECT age FROM user;
type = index
6.
SELECT * FROM user WHERE name='Tom';
type = ALL
面试中的标准答案
如果面试官问:
EXPLAIN 中 type 的级别是什么?
你可以回答:
type表示 MySQL 的访问类型,从好到坏依次为:
system > const > eq_ref > ref > range > index > ALL
其中:
system:表只有 0 或 1 行;const:主键或唯一索引等值查询;eq_ref:JOIN 时使用主键或唯一索引关联;ref:普通索引等值查询;range:范围查询,如 >、<、BETWEEN、IN、LIKE 'xx%';index:全索引扫描;ALL:全表扫描。
实际工作中:
至少要达到 range,
最好是 ref,
主键查询达到 const。
如果线上 SQL 出现:
type = ALL
通常就需要重点排查是否缺少索引、索引失效或者 SQL 写法不合理。
浙公网安备 33010602011771号