[Java 面试突击训练] SQL 优化策略

本文主要探讨了SQL查询的执行计划及其字段含义,包括id、select_type、table、type等,强调了全值匹配、最佳左前缀法则、避免索引列上的操作等优化策略。此外,还提醒注意like查询、不等于操作、null的影响以及如何有效利用覆盖索引。
摘要由CSDN通过智能技术生成

执行计划的字段

id
  • id 相同,执行顺序由上至下
  • id 不同,如果是子查询,id 的序号会递增,id 值越大优先级越高,越先被执行
  • id 相同、不同都存在,则相同的时一组,由上至下顺序执行,所有组中,id 值越大越先执行
select_type
类型描述
SIMPLE简单的select查询,不包含子查询或者union
PRIMARY查询中若包含任何复杂的子部分,最外层查询则被标记为primary
SUBQUERY在select或where列表中包含了子查询
DERIVED在from列表中包含的子查询被标记为derived(衍生),MySQL会递归执行这些子查询,把结果放在临时表里
UNION若第二个select出现在union之后,则被标价为union;若union包含在from子句的子查询中,外层select将被标记为derived
UNION RESULT从union表获取结果的select
table

显示这一行的数据是关于哪张表的

type

显示访问类型,重要指标,从好到坏依次为
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

类型描述
system表只有一行记录(等于系统表),这是 const 的特例,平时不会出现
const表示通过索引一次就找到了,const 用于比较 primary key 或者 unique 索引。因为只匹配一行数据,所以很快。
eq_ref唯一性索引扫描,对于每个索引键,表只有一条记录与之匹配。常见于主键或唯一索引扫描
ref非唯一性索引扫描,返回匹配某个单独值的所有行
range只检索给定范围的行,使用一个索引来选择行,key字段显示使用了哪个索引。一般就是 where 语句中出现了 between、<、>、in 等的查询
index当查询的结果全为索引列的时候
ALL什么索引也不用,全表查询以找到匹配的行
possible_keys

可能用到的索引

key
  • 实际使用的索引,如果为 NULL,则没有使用索引
  • 查询中若使用了覆盖索引,则该索引和查询的 select 字段重叠
key_len
  • 表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度。在不损失精确性的情况下,长度越短越好。
  • 它显示的值为索引字段的最大可能长度,并非实际使用长度,即 key_len 是根据表定义计算而得,不是通过表内检索出的。
  • char 和 varchar 的长度与字符集编码有关,latin1 占 1 个字节,gbk 占 2 个字节,utf8 占 3 个字节。

字符串类型

类型大小用途
CHAR0-255 字节定长字符串
VARCHAR0-65535 字节变长字符串
TINYBLOB0-255 字节不超过 255 个字符的二进制字符串
TINYTEXT0-255 字节短文本字符串
BLOB0-65535 字节二进制形式的长文本数据
TEXT0-65535 字节长文本数据
MEDIUMBLOB0-16777215 字节二进制形式的中等长度文本数据
MEDIUMTEXT0-16777215 字节中等长度文本数据
LONGBLOB0-4294967295 字节二进制形式的极大文本数据
LONGTEXT0-4294967295 字节极大文本数据
ref

显示索引的哪一列被使用了,如果可能的话,是一个常数。

rows

根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数。

Extra

包含不适合在其他列中显示但十分重要的额外信息

描述
Using filesort说明 MySQL 会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取。MySQL 中无法利用索引完成的排序操作称为“文件排序”
Using temporary使用了临时表保存中间结果,MySQL 在对查询结果排序时使用临时表。常见于排序 order by 和分组查询 group by
Using index是否用了覆盖索引
Using where表明使用了 where 过滤
Using join buffer使用了连接缓存
Impossible wherewhere 子句的值总是 false,不能用来获取任何元组

查询策略

尽量全值匹配

尽量使用全部的索引列查询

最佳左前缀法则

如果索引用了多列,要遵守最做前缀法则。指的是查询从索引的最左前列开始并且不跳过索引中的列。

不在索引列上做任何操作

不要做任何操作(计算、函数、类型转换),会导致索引失效而转向全表扫描

范围条件放最后

存储引擎不能使用索引中范围条件右边的列。

尽量使用覆盖索引

只访问索引的查询(索引列和查询列一致),减少 select *

不等于要慎用

MySQL 在使用不等于时候无法使用索引,会导致全表扫描

not / null 有影响
like 查询要当心

like 以通配符开头,MySQL 索引失效会变成全表扫描

字符类型加引号

字符串不加单引号索引失效

or 改 union 效率高
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值