索引是帮助MySQL高效获取数据的排好序的数据结构,根据索引找到存储地址
索引数据结构
二叉树
红黑树
Hash表
B-Tree
二叉树:
树(Tree)是n(n>=0)个结点的有限集。n=0时称为空树。在任意一颗非空树中:
1)有且仅有一个特定的称为根(Root)的结点;
2)当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1、T2、......、Tn,其中每一个集合本身又是一棵树,并且称为根的子树。
此外,树的定义还需要强调以下两点:
1)n>0时根结点是唯一的,不可能存在多个根结点,数据结构中的树只能有一个根结点。
2)m>0时,子树的个数没有限制,但它们一定是互不相交的。
示例树:
红黑树:
自平衡,不同于二叉树。如果二叉树都是递增的元素的时候,那么就会变成单向的链式结构。
hash表:
Hash索引仅仅能满足“=”,“IN”,“<=>”查询,不能使用范围查询。
联合索引中,Hash索引不能利用部分索引键查询。
对于联合索引中的多个列,Hash是要么全部使用,要么全部不使用,并不支持BTree支持的联合索引的最优前缀,也就是联合索引的前面一个或几个索引键进行查询时,Hash索引无法被利用。
Hash索引无法避免数据的排序操作
由于Hash索引中存放的是经过Hash计算之后的Hash值,而且Hash值的大小关系并不一定和Hash运算前的键值完全一样,所以数据库无法利用索引的数据来避免任何排序运算。
Hash索引任何时候都不能避免表扫描
Hash索引是将索引键通过Hash运算之后,将Hash运算结果的Hash值和所对应的行指针信息存放于一个Hash表中,由于不同索引键存在相同Hash值,所以即使满足某个Hash键值的数据的记录条数,也无法从Hash索引中直接完成查询,还是要通过访问表中的实际数据进行比较,并得到相应的结果。
Hash索引遇到大量Hash值相等的情况后性能并不一定会比BTree高
对于选择性比较低的索引键,如果创建Hash索引,那么将会存在大量记录指针信息存于同一个Hash值相关联。这样要定位某一条记录时就会非常麻烦,会浪费多次表数据访问,而造成整体性能底下。
btree:
不同于红黑树,除了自平衡外,叶子节点可以存在多个元素,最多为16k。但是key value存在一块会导致整个叶子节点的存量变大。
它会将某个叶子节点load到内存中进行比较,从而确定某个值。并且叶子节点的值是从链式结构顺序排序的
btree+:
b+tree 在btree树上做了改造。叶节点不在存储value,置存储冗余的叶节点,这样保证子节点全部存在在最底层。链式结构能包围,每个叶节点可以存储的key也增加了。方便做范围查询。
mysql查询
explain中的列 接下来我们将展示 explain 中每个列的信息。
1. id列 id列的编号是 select 的序列号,有几个 select 就有几个id,并且id的顺序是按 select 出现的 顺序增长的。 id列越大执行优先级越高,id相同则从上往下执行,id为NULL最后执行。
2. select_type列 select_type 表示对应行是简单还是复杂的查询。
1)simple:简单查询。查询不包含子查询和union mysql> explain select * from film where id = 2;
2)primary:复杂查询中最外层的 select subquery:
3) 包含在 select 中的子查询(不在 from 子句中)
4)derived:包含在 from 子句中的子查询。MySQL会将结果存放在一个临时表中,也称为 派生表(derived的英文含义) 用这个例子来了解 primary、subquery 和 derived 类型
用这个例子来了解 primary、subquery 和 derived 类型
mysql> set session optimizer_switch='derived_merge=off'; #关闭mysql5.7新特性对衍 生表的合并优化
mysql> explain select (select 1 from actor where id = 1) from (select * from film where id = 1) der;
5)union:在 union 中的第二个和随后的 select mysql> explain select 1 union all select 1;