MySQL高级知识点(三)

MySQL高级知识点(三)

文章目录

  • MySQL高级知识点(三)
    • 4、MySQL的索引
      • B树与B+树
        • 区别
      • MySQL中的B+树
        • 主键索引
        • 复合索引
    • 5、索引的使用场景
      • 适合索引的场景
      • 不适合索引的场景

4、MySQL的索引

B树与B+树

MySQL高级知识点(三)_第1张图片

MySQL高级知识点(三)_第2张图片

区别

  • B树的关键字和记录是放在一起的,叶子节点可以看作外部节点,不包含任何信息;B+树的非叶子节点中只有关键字和指向下一个节点的索引,记录只放在叶子节点中
  • 在 B树中,越靠近根节点的记录查找时间越快,只要找到关键字即可确定记录的存在;而 B+树中每个记录 的查找时间基本是一样的,都需要从根节点走到叶子节点,而且在叶子节点中还要再比较关键字。从这个角度看 B树的性能好像要比 B+树好,而在实际应用中却是 B+树的性能要好些。因为 B+树的非叶子节点不存放实际的数据, 这样每个节点可容纳的元素个数比 B树多,树高比 B树小,这样带来的好处是减少磁盘访问次数。尽管 B+树找到 一个记录所需的比较次数要比 B树多,但是一次磁盘访问的时间相当于成百上千次内存比较的时间,因此实际中 B+树的性能可能还会好些,而且 B+树的叶子节点使用指针连接在一起,方便顺序遍历(例如查看一个目录下的所有 文件,一个表中的所有记录等),这也是很多数据库和文件系统使用 B+树的缘故

为什么说 B+树比 B-树更适合实际应用中操作系统的文件索引和数据库索引?

  • B+树的磁盘读写代价更低
    • B+树的内部结点并没有指向关键字具体信息的指针。因此其内部结点相对 B 树更小。如果把所有同一内部结点 的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多。相对来说 IO 读写次数也就降低了
  • B+树的查询效率更加稳定
    • 由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当

MySQL中的B+树

主键索引

MySQL高级知识点(三)_第3张图片

MySQL在创建表时,会根据主键来创建主键索引(如果没有主键,会用一个隐藏值来作为主键)。主键索引所构建的B+树,表中所有的记录都存放在了树的最后一层。且与一般的B+树不同的是:叶子节点间的指针是双向的

复合索引

MySQL高级知识点(三)_第4张图片

创建复合索引时,会将作为复合索引字段的值进行排序并放在B+树的最后一层中,同时还会将其对应的主键值放在其后。如:

a(主键) b c d e
2 1 1 1 a

其中字段a为主键,字段bcd共同作为复合索引,此时存放在最后一层的数据就是:111(复合索引) 2(主键索引)

根据这个特点,可以看出复合索引具有以下使用方法

  • 最佳左前缀:使用复合索引的顺序必须和创建的顺序一致

  • 覆盖索引的同时,可以带上主键字段,如

    SELECT a, b, c, d FROM t_emp;
    

    因为主键字段和复合索引一起存放在了复合索引说产生的B+树的最后一层。如果需要a字段,无需进行全表扫描

  • 如果进行范围查找,可能会进行全表扫描,这取决于处在范围内记录的多少

    • 记录多,从复合索引映射到主键索引的次数过多,成本过高,会直接进行全表扫描

      EXPLAIN SELECT * FROM t_emp WHERE age > 1;
      

      img

    • 记录少,先使用复合索引,然后映射到全表中的对应记录上

      EXPLAIN SELECT * FROM t_emp WHERE age > 80;
      

      img

    • 但是使用覆盖索引,无论记录多少,都会用到索引

      EXPLAIN SELECT age, name FROM t_emp WHERE age > 1;
      

      img

  • 不带WHERE也可以通过复合索引查找到主键+复合索引的记录

    EXPLAIN SELECT id, age, name, deptId FROM t_emp ;
    

    img

5、索引的使用场景

适合索引的场景

  • 主键自动建立唯一索引
  • 频繁作为查询条件的字段应该创建索引
  • 查询中与其它表关联的字段,外键关系建立索引
  • 单键/组合索引的选择问题,组合索引性价比更高
  • 查询中排序的字段,排序字段若通过索引去访问将大大提高排序速度
  • 查询中统计或者分组字段

不适合索引的场景

  • 记录太少(有无索引差别不大)
  • 经常增删改的表或者字段
  • Where 条件里用不到的字段不创建索引
  • 过滤性不好的不适合建索引(重复性较高,比如国籍、性别之类的字段)

你可能感兴趣的:(mysql,mysql,b树,数据库)