MySQL/MariaDB的 B+ TREE索引

在我们CentOS 7+版本之后的自带镜像中的MariaDB使用的默认引擎是InnoDB引擎:


InnoDB引擎自带的特点:

    1.InnoDB存储引擎将数据存储于"表空间"中;

    2.支持事务

    3.精细锁粒度支持;表级锁、页级锁、行级锁、间隙锁;

    4.支持聚集索引,主键索引以及辅助索引,自适应的Hash索引;


简要介绍一下事务:


所谓事务:就是一组原子性的SQL查询或者是一个或多个SQL语句组成的独立的操作单元;

一个最简单易懂的事务例子:

    A 借 B 100块钱,A 得到100,则相应的 B 就会减少100;这就是一个事务,因为不可能 A 借 B100之后,A增加了,而B却没减少;


对事务支持性能的测试标准;ACID标准;

    A:原子性、整个事务中所有的操作是一个不可分割的整体,要么全部成功执行,要么在某操作执行失败后全部回滚值事务开启时的状态;

    C:一致性、数据库的状态在执行事务之前和提交事务之后必须要保持数据状态一致性;

    I:隔离性、独立性、并发控制的管理机制;

    D:持久性、事务一旦提交,其所作出的所有修改将永久保存并持久有效;



B+ TREE索引:

    顺序存储,所有的索引数据都存放在叶节点上,并且每个叶节点都有顺序访问指针,以此指针指向相邻的叶子节点。这样做可以提高区间数据的查询效率;


适用的场景:

全键值匹配:精确匹配某个值;

select ... where Name='guo jing';

左前缀匹配:只精确到数据起始位置的一部分;

select ... where Name like 'guo%';

区间数据的连续数值匹配:通常用于BETWEEN ... AND ...环境中;

select ... where Age between 30 and 50;

区间数据的离散值匹配:通常用于IN列表环境或OR列表环境:也是精确值匹配;

select ... where StuID in (1,4,7,10);

精确匹配左列,范围匹配右侧其他列:

select ... wherer StuID > 10 and Name like "a%";

对于覆盖索引的查询请求:


不适用的场景:

如果查询条件不是精确从最左侧列开始的,索引无效;

如:对StuID字段做了索引,select ... where Name like 'a%' and 'StuID' > 10;

如果索引了多列,若跳过索引中的某列,则索引无效;

如:对StuID,Name,Age做索引,select ... where StuID>0 and Age>20;

如果索引了多列,且在查询语句中对某个列做范围匹配,则其右侧列不能在使用索引优化查询;

如:对StuID,Name,Age做索引,select ... where StuID>0 and Name like 'a%';


    HASH索引:基于HASH表实现的索引;非常适用于值的精确匹配的查询请求;


注意:

    1.在InnoDB存储引擎中,创建索引时,只能显式使用"B+ TREE"索引;

    2.索引中的数据来源于数据表,但数据结构与原数据有很大差异;


查看数据库的索引:用EXPLAIN语句;

MariaDB [hellodb]> explain select  * from students where StuID<10\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: students
         type: range
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: NULL
         rows: 9
        Extra: Using where
1 row in set (0.00 sec)


id:当前的SELECT查询语句中,各个SELECT语句的编号;

select_type:查询类型:

简单查询:SIMPLE

复杂查询:

简单的子查询(用于where子句中的子查询):SUBQUERY

用于FROM语句中的子查询:DERIVED

联合查询中的第一个查询:PRIMARY

联合查询中其他的查询:UNION

联合查询时生成的临时表查询:UNION RESULT


table:当前的查询语句所针对的表;

type:关联类型,或称为访问类型;也可以理解为MySQL是如何查询表中的行;

ALL:全表扫描,MySQL将遍历权标以找到可以匹配的行;

index:全部扫描,与ALL所不同的是index类型只是遍历索引树;

range:索引范围扫描,对索引的扫描从某一个点开始,返回匹配值域的行;

通常可以基于指定的索引,使用IN列表、BETWEEN ... AND ...或带有哦"=","<", ">"的查询;

ref:使用非唯一索引扫描或者使用唯一索引的左前缀扫描,返回匹配某个单独的行;

eq_ref:类似ref,区别就是使用唯一索引,对于每一个索引键值,表中都只有一条记录匹配;无论是单表查询还是多表查询,都是要主键或唯一键索引作为关联条件;

const,system:当MYSQL对查询部分进行优化,并转换为一个常量,使用const类型;

system类型是一个const类型特例,当要查询的表中只有一行时,使用system类型;

NULL:MySQL在优化过程中分解查询语句,执行时不用访问表或索引;

possible_keys:为了执行查询语句,MySQL可能使用哪个索引在表中查找到记录;

如果查询涉及到的字段上存在索引,则该索引会被列出,但不一定会被查询使用;

keys:显示MySQL在查询过程中实际使用到的索引;如果查询过程没有用到任何索引,则此处显示为"NULL";

key_len:表示索引中可以被引用的最大的字节数;可以通过该列计算查询中使用的索引的长度:

注意:key_len显示的值通常为索引字段的最大可能长度,并不是实际的使用长度;因此key_len是根据定义时指定的字段长度计算得到的,而并不是在表中通过检索数据得到的;

ref:在利用key字段所显示的索引完成查询操作时所引用的列或常量值;如果都没有,则显示为"NULL";

rows:表示MySQL根据表统计信息及索引选用的情况,估算的本次检索所需要查找索引记录的过程中需要读取的表的行数;

Extra:额外信息,或称为扩展信息;

Using where:表示MySQL服务器将在存储检索后在次进行条件过滤;许多的where条件里涉及到索引中的列并且当MySQL读取该索引时,就可以被存储引擎检验;

Using index:使用了覆盖索引进行检索;

Using tempory:在查询过程中使用了临时表存放查询结果集;常见于排序或分组查询;

Using filesort:MySQL中无法利用索引完成排序;

Using join buffer:强调了在获取连接条件时没有使用都索引,并且需要连接缓冲区来存储中间结果;如果出现了该值,需要根据查询的具体情况适当的添加索引以提示查询性能;

Impossible where:如果该值出现,则意味着在查询时没有发现符合条件的行;

Select tables optimized away:该值意味着仅通过使用索引来进行查询,但是优化器可能从聚合函数的结果中给出一个可行的优化方案;

Using sort-union(...)

Using union(...)

Using intersect(...)


上述情况多出现于在实现查询的过程中,决定使用不止一个索引时;


filtered:从可选的行中再次过滤之后选择出最终的查询结果的比值;可以理解为从多少行中过滤选择出多少行的比值;

相关文章
相关标签/搜索
每日一句
    每一个你不满意的现在,都有一个你没有努力的曾经。
公众号推荐
   一个健康类的公众号,欢迎关注
小青桔健康