数据库索引
基础知识
二叉树:一个节点最多有两个子节点
平衡树:所有节点的深度差不大于1
查找树:节点的值是排序过的,左节点小于右节点
B+树:按上面三种树的分类,B+树是多叉平衡查找树。
当我们要查找值V时,就用V与节点中的keys一一对比(节点中的keys是有序的),确定出相应的childNode,然后再去childNode中对比。
//B+树节点的数据结构
public class Node { //节点分为两种类型,叶子节点和普通节点
public boolean isLeaf = false; //是否为叶子节点
public Node parent = null; //父节点
public ArrayList<Object> keys = new ArrayList<Object>(); //普通节点的索引
public ArrayList<Node> childNodes = new LinkedList<Node>(); //子节点
public ArrayList<Object> values = new LinkedList<Object>(); //叶子节点的值
public Node right = null; //右兄弟节点
public Node left = null; //左兄弟节点
}
InnoDB索引
InnoDB引擎支持B+树索引。
数据库从大到小的结构可以分为段(Segment)、区(extent)、页(page)、表(Table)、行(Row),每个页默认是16KB大小。B+树数据结构中的节点就是这里的页,即InnoDB通过B+树索引只能定位到页,在页中的继续查找就不是靠索引了。
在页面中的查找需要先用二叉法查找目录槽,然后根据目录槽给出的大致位置再去顺序查找精确的行。
如果多个行记录的主键为(1,2,3,4,5,6,7,8),那么目录槽可能就由其中的部分组成,如(1,5,8)。
数据库中的B+树往往层数比较少,一般在2~4层。数据库查找数据时,会一次性从磁盘中读取多个连续的页(即多个连续的B+树节点)进内存。在内存中查找目标索引和目标子节点。当从父节点跨层到子节点时,往往要重新进行一个磁盘读取,而磁盘IO往往是最耗时间的。为了减少磁盘IO,树的层数应该尽量少,但也不能太少,如果少到极致只有1层的话,那就退化为节点内的顺序或者二叉查找了。
索引的分类
聚集索引
以主键为索引建立B+树,且叶子节点中有记录的全部列数据。
聚集索引建立的B+树只有一个。
非聚集索引(辅助索引)
以指定键值建立B+树,且叶子节点中没有全部列数据,叶子节点中有指定键值和该条记录的主键。
辅助索引建立的B+树可以有多个。
索引的使用
联合索引
可以将多列合并作为一个索引,这几个列是有顺序的。如果将(col1,col2)作为联合索引,会先排列col1,再排列col2.
覆盖索引
覆盖索引是指查找过程在辅助索引树上就可以结束,不需要到聚集索引树上查找。要达到这样的效果,就需要将多个需要的列作为一个联合索引建立起来。