MySql索引以及优化-日常充电

Posted JF Coder

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySql索引以及优化-日常充电相关的知识,希望对你有一定的参考价值。

索引是帮助MySql高效获取数据的排好序的数据结构

索引的数据结构

二叉树,红黑树,Hash表,B-Tree

创建索引

ALTER TABLE用来创建普通索引、UNIQUE索引或PRIMARY KEY索引。

ALTER TABLE table_name ADD INDEX index_name (column_list)
ALTER TABLE table_name ADD UNIQUE (column_list)
ALTER TABLE table_name ADD PRIMARY KEY (column_list)

CREATE INDEX可对表增加普通索引或UNIQUE索引。

CREATE INDEX index_name ON table_name (column_list)
CREATE UNIQUE INDEX index_name ON table_name (column_list)

其中table_name是要增加索引的表名,column_list指出对哪些列进行索引;另外,不能用CREATE INDEX语句创建PRIMARY KEY索引。

删除索引

可利用ALTER TABLE或DROP INDEX语句来删除索引。类似于CREATE INDEX语句,DROP INDEX可以在ALTER TABLE内部作为一条语句处理,语法如下。

DROP INDEX index_name ON talbe_name
ALTER TABLE table_name DROP INDEX index_name
ALTER TABLE table_name DROP PRIMARY KEY

索引存储方式

  • B+Tree(mysql默认索引存储数据结构)

  • Hash
  • 对索引的key进行一次hash计算就可以定位出数据存储的位置

  • 很多时候Hash索引要比B+Tree索引高效

  • 仅满足“=”,“IN”,不支持范围查询

  • hash冲突问题

如图Hash的算法:value % 13 = index

  • 扩展B树(注意和B+Tree的区别)

MyISAM和InnoDB实现BTree索引方式的区别

MyISAM存储引擎索引实现

B+Tree叶节点的data域存放的是数据记录的地址。在索引检索的时候,首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其 data 域的值,然后以 data 域的值为地址读取相应的数据记录。这被称为“非聚簇索引”。

MyISAM索引文件和数据文件是分离的 ;如图:myisam表文件

InnoDB存储引擎索引实现

其数据文件本身就是索引文件。相比MyISAM,索引文件和数据文件是分离的,其表数据文件本身就是按B+Tree组织的一个索引结构,树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。这被称为“聚簇索引(或聚集索引)”

InnoDB表数据文件本身就是主索引 如图:innodb表文件

聚集索引的优点

聚集索引查找的速度非常的快,因为整个B+树本身就是的多叉平衡树,叶子节点是有序的,所以找到了索引就等于是找到了相应的数据

聚集索引的缺点
  1. 依赖于有序的数据。B+树本身就是多叉平衡树,如果索引的数据不是有序的,那么就需要在插入的时候进行排序,如果数据是整刑还比较好操作,如果是字符串或者是uuid这种又长又难比较的数据,插入和查找的速度肯定就很慢了

  2. 更新代价比较大。如果索引列的数据被修改,那么相应的索引也要修改,加上聚集索引的叶子节点上还存放了数据,修改的代价就更大了。所以对于主键索引来说,一般主键是不允许修改的。

为什么建议InnoDB的表要建议设置主键,并且推荐使用整型的自增主键? 如果没有设置主键,InnoDB会选择一个不包含null值的唯一索引作为主键索引;如果没有选到唯一值的索引列,mysql会帮忙建立一个隐藏列,维护一个唯一id,以此来组织索引,那么为了避免 mysql选择索引列和建立隐藏列的性能损耗,建议手动建立一个主键。

索引分类

  1. 单值(普通)索引:即一个索引只包含单个列,一个表可以有多个单值索引;NORMAL
  2. 唯一索引:索引列的值必须唯一,单允许空值;UNIQUE
  3. 全文索引:表示全文收索,在检索长文本的时候,效果最好;FULLTEXT
  4. 空间索引:MYSQL使用SPATIAL关键字进行扩展,使得能够用于创建正规索引类型的语法创建空间索引。创建空间索引的列,必须将其声明为NOT NULL,空间索引只能在存储引擎为MYISAM的表中创建;

建议需要创建索引

  1. 主键自动建立唯一索引(设置表的主键就自动创建索引)
  2. 频繁作为查询条件的字段应该创建索引
  3. 查询中与其它表关联的字段,外键关系建立索引
  4. 频繁更新的字段不适合创建索引,因为每次更新记录还会更新索引
  5. where条件里用不到的字段不创建索引
  6. 单键/组合索引的选择(高并发下倾向创建组合索引)
  7. 查询中排序的字段,排序字段若通过索引访问将提高排序速度
  8. 查询中统计或者分组字段(orderby 分组前要排序)

不建议创建索引

  1. 表记录太少
  2. 经常增删改的表
  3. 某个数据列包含许多重复的内容,为它建立索引就没有太大的实际效果

性能分析

EXPLAIN关键字,来查看索引是否正在被使用,并且输出其使用的索引信息

**id:**为SELECT的识别符。这是SELECT的查询序列号,如果是子查询,id序号会递增,id的值越大优先级越高。
**select_type:**表示使用SELECT的查询类型,SIMPLE表示为简单的SELECT,不适用于UNION或子查询,就是简单的SELECT。也就是说该SELECT查询时会使用索引。其他取值:

**PRIMARY:**最外面的SELECT,在有子查询时,就会出现两个以上的SELECT。

**UNION:**union(两张表连接)中的第二个或后面的select语句。

**SUBQUERY:**在子查询中,第二个SELECT。

**table:**数据表的名字。按照被读取的先后顺序排列,这里只查询一张表,所以只显示book。

**type:**显示的是访问类型,是较为重要的指标,结果值从好到坏(一般大于range就差不多了)system(系统表)>const>eq_ref>ref>range>index>All。

Type访问类型 system(系统表)>const>eq_ref>ref>range>index>All
const表示通过索引一次就找到了,const用于比较primary key或者unique索引
eq_ref唯一索引扫描,表中一条记录与之匹配
ref非唯一索引扫描,返回匹配某个单独值的所有行
range只检索给定范围的行,使用一个索引来选择行,比index强
indexindex和All都是读全表,但是index是从索引中读取的,而All是从硬盘中读取的
建议:最好达到range以上,可做sql优化达到

**possible_keys:**显示可能应用在这张表中的索引,一个或者多个。

**key:**实际选用的索引,如果为null则没有使用索引。

key_len:显示了mysql使用索引的长度(也就是使用的索引个数),长度越短越好。注意,key_len的值可以告诉你在联合索引中mysql会真正使用了哪些索引。

ref:用于连接程序使用键的最左前缀或者是该键不是 primary key 或 unique索引;可能的取值有 system、const、eq_ref、index和All。

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

**extra:**提供了与关联操作有关的信息,没有则什么都不写。

extra提供了与关联操作有关的信息
Using filesort说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行,Mysql无法利用索引完成的排序操作称为“文件排序”
Using temporary使用了临时表保存中间结果,Mysql在对查询结果排序时使用临时表,常见于排序orderby和分组查询groupby,union等;
Using index表示相应的select操作使用了覆盖索引(Covering Index),避免访问表的数据行,如果同时出现using where,表明索引被用来执行索引键值的查找;如果没有出现using where,表明索引用来读取数据而非执行查找动作;
Using where表示使用了where查询
using join buffer使用了连接缓存 (使用join多了,配置文件的join buffer可以调大)
impossible wherewhere子句的值总是false,不能用来获取元组

覆盖索引(Covering Index):索引是可以高效找到行的方法,但是一般数据库也能使用索引找到一个列的数据,因此不必读取整个行;毕竟索引叶子节点(BTree)存储了要索引的数据,当能通过读取索引就可以拿到数据,就不需要读取行了,一个索引包含(覆盖)了满足查询结果的数据就叫做覆盖索引;可以减少回表查询;

案例分析

待完善

以上是关于MySql索引以及优化-日常充电的主要内容,如果未能解决你的问题,请参考以下文章

MySql索引以及优化-日常充电

MySql索引以及优化-日常充电

Mysql索引以及优化

MySQL 索引原理以及查询优化

聊聊Mysql优化之索引优化

MySQL索引基础补充以及优化笔记-下