MySQL面试主题:索引

索引分类

索引是在存储引擎中实现的,也就是说不同的存储引擎,会使用不同的索引。MyISAM和InnoDB存储引擎:只支持BTREE索引,也就是说默认使用BTREE,不能够更换。MEMORY/HEAP存储引擎:支持HASH和BTREE索引。

mysql的索引我们分为三大类来讲单列索引(普通索引,唯一索引,主键索引)、组合索引、全文索引。

  1. TextField是不支持建立索引的
  2. MySQL对索引字段长度有限制innodb引擎的每个索引列长度限制为767字节(bytes),所有组成索引列的长度和不能大于3072字节myisam引擎的每个索引列长度限制为1000字节,所有组成索引列的长度和不能大于1000字节
  3. varchar的最大长度是指字符长度,若数据库字符集为utf-8,则一个字符占3个bytes。因此在utf-8字符集下,innodb引擎创建的单列索引长度不能超过255个字符

在MySQL5.6里默认 innodb_large_prefix=0 限制单列索引长度不能超过767bytes。

在MySQL5.6里面,设置了innodb_large_prefix=ON、innodb_file_format=barracuda、innodb_file_per_table=ON ,且Innodb表的存储格式为 DYNAMIC 或 COMPRESSED,则前缀索引最多可包含3072个字节,前缀索引也同样适用。

在MySQL5.7里默认 innodb_large_prefix=1 解除了767bytes长度限制,但是单列索引长度最大还是不能超过3072bytes

MyISM中的B+树中叶子节点的数据区域存储的是数据记录的地址

MyISAM存储引擎在使用索引查询数据时,会先根据索引查找到数据地址,再根据地址查询到具体的数据。并且主键索引和辅助索引没有太多区别。

Innodb中的B+树中主键索引的叶子节点的数据区域存储的是数据记录,辅助索引存储的是主键值


Innodb中的主键索引和实际数据时绑定在一起的,也就是说Innodb的一个表一定要有主键索引,如果一个表没有手动建立主键索引,Innodb会查看有没有唯一索引,如果有则选用唯一索引作为主键索引,如果连唯一索引也没有,则会默认建立一个隐藏的主键索引(用户不可见)。另外,Innodb的主键索引要比MyISAM的主键索引查询效率要高(少一次磁盘IO),并且比辅助索引也要高很多。所以,我们在使用Innodb作为存储引擎时,我们最好:

  1. 手动建立主键索引
  2. 尽量利用主键索引查询

回到我们的问题:为什么一个节点为1页(16K)就够了?

  对着上面Mysql中Innodb中对B+树的实际应用(主要看主键索引),可以发现B+树中的一个节点存储的内容是:

    1. 非叶子节点:主键 + 指针

    2. 叶子节点:数据

  那么,假设我们一行数据大小为1K,那么一页就能存16条数据,也就是一个叶子节点能存16条数据;再看非叶子节点,假设主键ID为bigint类型,那么长度为8B,指针大小在Innodb源码中为6B,一共就是14B,那么一页里就可以存储16K/14=1170个(主键+指针),那么一颗高度为2的B+树能存储的数据为:1170 * 16=18720条,一颗高度为3的B+树能存储的数据为:1170 * 1170 * 16=21902400(千万级条)。所以在InnoDB中B+树高度一般为1-3层,它就能满足千万级的数据存储。在查找数据时一次页的查找代表一次IO,所以通过主键索引查询通常只需要1-3次IO操作即可查找到数据。所以也就回答了我们的问题,1页=16k这么设置是比较合适的,是适用大多数的企业的,当然这个值是可以修改的,所以也能根据业务的时间情况进行调整。

You May Also Like

About the Author: daidai5771

发表评论

电子邮件地址不会被公开。 必填项已用*标注