数据库索引优化
一、Btree索引和Hash索引
索引的主要作用就是告诉存储引擎如何快速的找到我们锁需要的数据。当表中的数据比较少、查询的效率也比较低的情况下,索引的作用还不是太明显,因为这时表中的数据都可以缓存到内存中,所以就算是进行全表扫描,也不会太慢;而随着表中的数据越来越大,查询频率也越来越高,内存已经不能完全缓存表中数据的时候,索引的作用就会显得越来越重要。
MySQL的索引是在存储引擎层实现的。
1、MySQL支持的索引类型
(1) B-tree索引的特点
a、B-tree索引以B+树的结构存储数据;
B+ 树是一种数据结构,是一个n叉树,每个节点通常有多个孩子,一棵B+树包含根节点、内部节点和叶子节点。根节点可能是一个叶子节点,也可能是一个包含两个或两个以上孩子节点的节点。
B+树通常用于数据库和操作系统的文件系统中。
NTFS,ReiserFS,NSS,XFS,JFS,ReFS和BFS等文件系统都在使用B+树作为数据索引。
B+树的特点是能够保持数据稳定有序,其插入与修改拥有较稳定的对数时间复杂度。
B+树元素自底向上插入。
所有的叶子节点中包含了全部关键字信息,及指向含有这些关键字记录的指针,且叶子节点本身依关键字的大小自小而大的顺序链接。
所有的非终端节点可以看成是索引部分,节点中仅含有其子树根节点中最大(或最小)关键字。
1)有n棵子树的节点中含有n个关键字;
2)所有的叶子节点中包含了全部关键字的信息,及指向含有这些关键字记录的指针,且叶子节点本身依赖关键字的大小自小而大的顺序链接;
3)所有的非终端节点可以看成的索引部分,节点中含有其子树根节点中最大(最小)关键字。
B+树的有效内容均在叶子节点;
B+树的头指针有两个,一个指向根节点,另一个指向关键字最小的元素,因此B+树又两种遍历的方式:
1. 从根节点开始随机查询;
2. 从最小关键词顺序查询。
b、B-tree索引能够加快数据的快速查找;
c、B-tree索引更适合进行范围查找。
(2) 在什么情况下可以用到B树索引
a、全值匹配的查询
order_sn = "9876432119900"
b、匹配最左前缀的查询
c、匹配前缀查询
order_sn like "9876%"
d、匹配范围值的查询
order_sn > "9876432119900" and order_sn < "9876432119999"
e、精确匹配左前列并范围匹配另一列
f、只访问索引的查询
(3) Btree索引的使用限制
a、如果不是按照索引最左列开始查找,则无法使用索引
b、使用索引时不能跳过索引中的列
假如由订单日期、下单人姓名、下单人电话三列所组成的联合索引,如果我们在查找中只包含了订单日期和下单人的电话。那么对于这个查询来说就只能用到订单日期这一列来进行查询过滤,而无法使用下单人电话这一列,因为我们跳过了下单人姓名这一列。
c、Not in 和 <> 操作无法使用索引
d、如果查询中有某个列的范围查询,则其右边所有列都无法使用索引
(4) Hash索引的特点
a、Hash索引是基于Hash表实现的,只有查询条件精确匹配Hash索引中的所有列时,才能够使用到hash索引。
b、对于Hash索引中的所有列,存储引擎都会为每一行计算一个Hash码,Hash索引中存储的就是Hash码。
(5) Hash索引的限制
a、Hash索引必须进行二次查找
b、Hash索引无法用于排序
c、Hash索引不支持部分索引查找也不支持范围查找
d、Hash索引中Hash码的计算可能存在Hash冲突
(6) 为什么要使用索引
a、索引大大减少了存储引擎需要扫描的数据量;
b、索引可以帮助我们进行排序以避免使用临时表;
c、索引可以把随机I/O变为顺序I/O。
(7) 索引是不是越多越好
a、索引会增加写操作的成本
b、太多的索引会增加查询优化器的选择时间