执行计划

169 阅读4分钟

执行计划

Explain + select语句

主要关键字

列名说明
id确定执行顺序。执行编号,标识select所属的行。如果在语句中没子查询或关联查询,只有唯一的select,每行都将显示1。否则,内层的select语句一般会顺序编号,对应于其在原始语句中的位置
select_type显示本行是简单或复杂select。如果查询有任何复杂的子查询,则最外层标记为PRIMARY(DERIVED、UNION、UNION RESUlT)
table访问引用哪个表(引用某个查询,如“derived3”)
type数据访问/读取操作类型(ALL、index、range、ref、eq_ref、const/system、NULL)
possible_keys揭示哪一些索引可能有利于高效的查找
key显示mysql决定采用哪个索引来优化查询
key_len显示mysql在索引里使用的字节数
ref显示了之前的表在key列记录的索引中查找值所用的列或常量
rows为了找到所需的行而需要读取的行数,估算值,不精确。通过把所有rows列值相乘,可粗略估算整个查询会检查的行数
Extra额外信息,如using index、filesort等

ID

确定执行顺序,小的先执行,相同可能是一组

Select_Type

Simple:通常

Primary:嵌套查询的主要查询,最外层

Union: Union后的查询

SubQuery: 嵌套子查询

Derived: 派生表的SELECT, FROM子句的子查询

Type

ALL, index, range, ref, eq_ref, const, system, NULL(从左到右,性能从差到好)

  • ALL 扫描全表数据
  • index 遍历索引
  • range 索引范围查找
  • index_subquery 在子查询中使用 ref
  • unique_subquery 在子查询中使用 eq_ref
  • ref_or_nullNull进行索引的优化的 ref
  • fulltext 使用全文索引
  • ref 使用非唯一索引查找数据
  • eq_refjoin查询中使用PRIMARY KEYorUNIQUE NOT NULL索引关联。
  • const 使用主键或者唯一索引,且匹配的结果只有一条记录。
  • system const 连接类型的特例,查询的表为系统表。

Extra

extra的信息非常丰富,常见的有:

1.Using index 使用覆盖索引

2.Using where 使用了用where子句来过滤结果集

3.Using filesort 使用文件排序,使用非索引列进行排序时出现,非常消耗性能,尽量优化。

4.Using temporary 使用了临时表

索引

mem引擎用hash,速度快,不支持范围查找

innodb B+树 一次16K

聚簇索引

聚簇索引:索引数据放在一起:innodb,索引放的是主键id,在回表查询,建立的其他索引是辅助索引(非聚簇索引)用于找到主键

非聚簇索引:分开放,myism,索引存放的是数据真正存放的行

MVCC

在读已提交和可重复读这两种隔离级别需要用到

基本原理是,每个事务有一个顺序的事务id,以及一个ReadView记录当前的活动事务列表,活动事务指的是开启中,还未提交的事务,如果在readview中,则意味着事务可见,通过undolog,找到数据

对于一个快照来说,它能够读到那些版本数据,要遵循以下规则:

  1. 当前事务内的更新,可以读到;
  2. 版本未提交,不能读到;
  3. 版本已提交,但是却在快照创建后提交的,不能读到;
  4. 版本已提交,且是在快照创建前提交的,可以读到;

已提交读:再次查询的时候更新事务id,可以看到其他事务新增的行,出现不可重复读。

可重复读:再次查询的时候不更新事务id

B树和B+树的区别

1.B+非叶子节点只存储索引,不存数据,可以放更多的索引

2.B+所有索引在叶子上都有一份冗余

3.B+树叶子节点之间有双向链表

4.B+树空间利用率高,IO次数少

索引失效的常见原因

1.最左前缀

2.隐士类型转换

使用cast函数进行类型转换,索引列上使用函数导致失效

3.使用全表扫描的速度更快

数据库锁

zhuanlan.zhihu.com/p/117476959

读锁:update xx in share mode;

行锁:select * from xx where id =1 for update;

锁的算法:

Record lock:单个行记录上的锁 Gap lock:间隙锁,锁定一个范围,不包括记录本身 Next-key lock:record+gap 锁定一个范围,包含记录本身 - 解决幻读问题

如果没有索引,只能锁整个表

数据库死锁

两个事务,相互访问互斥资源,无法释放导致死锁

按照顺序读表,一次锁定所需资源

解决:手动杀掉进程,设置事务超时时间,死锁后自动回滚事务

倒排索引 ES

正常索引 id-> 内容

倒排索引 内容->id

将内容分为关键词 -> term -> 建立字典 term dictionary -> 字典排序

关键词 包含关键词的文档id

Java 0,1,2,3