mysql的索引问题整理
1.索引的概述与分类
1.1索引是什么
官方回答:索引是帮助mysql高效获取数据的数据结构
通俗理解:为数据表添加完索引后,表中数据会以一种特殊结构相关联,大大加快数据的检索速度
1.2索引的分类
主键索引:
根据主键建立索引,不允许重复,不允许空值.如何没有主键innodb会选择一个唯一的非空索引代替
如果没有这样的索引,innodb会隐式的定义一个主键作为聚簇索引(后续解答);
唯一索引:用来建立索引的值必须是唯一的,允许空值。
添加语句:alter table 表名 add unique 索引名(列名)
普通索引:根据表中的列作为索引,没有任何限制
添加语句:alter table 表名 add index 索引名(列名)
全文索引:用大文本对象构建的索引
添加语句:alter table 表名 add fulltext index 索引名(列名)
注意:mysql5.6及之后的版本MyISAM和innodb都支持此索引,mysql8.x之前版本对中文还不支持
组合索引(最左原则):用多个列组合构建的索引(列中不允许有空值)
添加语句:添加语句:alter table 表名 add index 索引名(列名1,列名2,.....)
最左原则:查询条件中使用了组合索引中的第一个字段索引才会生效
附图:
2.索引原理
2.1简述基本原理
我们知道索引的目的是为了帮助mysql高效获取数据,如果让数据一个一个检索过滤,肯定失去了索引的意义。
mysql的innodb引擎给了一种非常高效的B+树作为数据存储和查找的数据结构.
了解B+树之前先简单铺垫一下二叉树,我们一般二叉树的用途是在有序的一堆数据中使用,举个简单例子
比如在如图二叉树中我们想找到6,只需中序遍历往左右对比大小两次就能找到6,可想数据量越大顺序执行遍历次数越多。
然而由于二叉树的每个节点只有两个造成树的深度过高性能下降,后面就有了专为磁盘等存储设备设计的的平衡多路查找树(多叉降低树高,也就是B树),B树会在数据插入的时候整理好数据结构,然后查找的时候类似于二叉树的遍历。不同的是有多叉来对比分支.如图
但是这样每一个节点都存储数据,遍历每一个节点的时候都要读取数据没到目标节点的时候就浪费了很多时间,于是
B+的改进是非叶子节点只起索引的作用,存储数据全部交给叶子结点并且所有的叶子结点用链表相连(如范围查找到对应区域后利用顺序索引的速度快).
3.SQL优化
一条mysql查询语句在经过mysql查询优化器的基于成本和规则的优化后会生成一个所谓的执行计划,
这个执行计划展示了我们接下来执行的语句的执行方式,比如多表连接的查询顺序,
每个表采用的查询方法,mysql为我们提供了explain语句帮我们查看语句使用的索引以及查询类型;
3.1创建并使用自增数字来建立主键索引
3.2经常作为where条件的字段添加索引
// 比如经常用表user的name字段在where后进行行筛选
alter table user add index index_name(name);
3.3添加索引的字段尽可能的保持唯一性
3.4可考虑使用联合索引并进行索引覆盖
这里需要注意的是聚簇索引和非聚簇索引;
简单地说主键索引及聚簇索引;其余的都是非聚簇索引;
区别!!!
聚簇索引:聚簇索引将索引和数据行保存在同一个B-Tree中,查询通过聚簇索引可以直接获取数据,
相比非聚簇索引需要第二次查询(非覆盖索引的情况下)效率要高
非聚簇索引:非聚簇索引,又叫二级索引。二级索引的叶子节点中保存的不是指向行的物理指针,而是行的主键值。
当通过二级索引查找行,存储引擎需要在二级索引中找到相应的叶子节点,获得行的主键值,
然后使用主键去聚簇索引中查找数据行,这需要两次查找如图:
3.5使用索引时的注意事项
1.每添加一个索引,都会为对应索引维持一个B+Tree的数据结构磁盘存储量大幅增加,不是索引越多越好.
而且为了维持表的平衡,大多数插入时会有一个数据结构的调整,影响插入速度.
2.隐式转换可能带来索引失效而造成全表扫描
3.使用like进行左侧通配的时候会失效
4.不要在where筛选的列上使用函数或计算如图