Mysql的索引是一个B树,相当于书的字典
索引的弊端
- 索引的本身很大(占用较大物理空间)
- 所以会降低增删改的效率
索引的分类
- 单值索引
- 唯一索引
- 复合索引
// 1.PRIMARY KEY(主键索引)
mysql>ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )
// 2.UNIQUE(唯一索引)
mysql>ALTER TABLE `table_name` ADD UNIQUE (`column` )
// 3.INDEX(普通索引)
mysql>ALTER TABLE `table_name` ADD INDEX index_name ( `column` )
// 4.FULLTEXT(全文索引)
mysql>ALTER TABLE `table_name` ADD FULLTEXT ( `column` )
// 5.多列索引
mysql>ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )
分析SQL的执行计划
// explain
explain select * from tb;
- id:编号
- select_type:查询类型
- table:表
- type:类型
- possible_keys:预测用到的索引
- key:实际使用的索引
- key_len:实际使用索引的长度
- ref:表之间的引用
- rows:通过索引查询到的数据量
- Extra:额外的信息
表的执行顺序因数量的个数改变而发生改变的原因: 笛卡尔积
ID
- ID相同,从上往下查询
- ID不同,从大到小查询
select_type
- PRIMARY:包含子查询SQL中的主查询(最外层)
- SUBQUERY:包含子查询SQL中的子查询(非最外层)
- SIMPLE:简单查询(不包含子查询、union)
- DERIVED:衍生查询(使用到了临时表)
type
system>const>eq_ref>ref>range>index>all
system,const只是理想情况,实际能达到ref,range
- const:仅仅能查到一条数据的SQL,用于Primary key和unique索引
- eq_ref:唯一性索引,对于每个索引键的查询,返回匹配唯一行数据(有且只有一个)
- ref:非唯一性索引,对于每个索引键的查询,返回匹配的所有行(可以为0行,可以为多行)
- range:检索指定范围的行, where后面是一个范围查询(between,>, <)
- index:查询全部索引的值
- all:查询全表的数据 like查询中,若查询行为索引,则XXX%为range,%xxx或者%xxx%为ALL
possible_keys , key
可能用到的索引和实际用到的索引
key_len
使用索引的长度,长度见基础.md,null用一个字节标识,可变用两个字节标识
ref
指明当前表所参照的字段
- const,常量
- xxx.xx,xxx表的xx字段
rows
实际通过索引查询到的数据条数
Extra
- using filesort : 性能消耗大,需要额外一次的排序
建议:where什么字段,就order by什么字段
- using temporary : 性能损耗大,用到了临时表。
- using index : 性能提升,索引覆盖
- using where : 需要回表查询
- using join buffer :引擎使用了连接缓存
优化案例
- 索引不要跨列使用
- =号查询条件提前,in查询后置
- where的解析顺序在前,select的解析顺序在后
- 小表优化大表,on的时候,左侧放小表,小表的连接字段要加索引
避免索引失效的一些原则
- 复合索引不要跨列或无序使用
# To Be Continued!😎
← Mysql主从复制 Mybatis常用语法 →