数据库-索引学习(以mysql为例)

索引:加快查询

前提介绍

新建表user:

idnameage
1张三18
2李四12
3王二13
4小明16

如果没有索引,select * from user where id = 1,需要全表扫描,查询效率极低。如果使用二叉排序树进行检索,则会快很多,但是二叉排序树会出现线性结构的二叉查找树,所以引出平衡二叉树来解决这个问题。
在这里插入图片描述

B-Tree(Balance Tree)

B-Tree是一个绝对平衡树,所有的叶子节点在同一高度。
B-Tree一个节点中包含的内容:
在这里插入图片描述

  • 关键字:建立索引的字段的值
  • 数据区:具体的数据或者是指向数据的指针
  • 指针:指向子孙的指针
    为了节省多次IO操作带来的性能消耗,B-Tree每个节点中存放多条记录数据(多个关键字),使得一次IO操作可以获取到更多记录数据。每个节点的关键字数=路数(指针数)-1。同时由于路数的增加,导致层数减少,IO操作也变少。
    在这里插入图片描述
    如果要从上图中查找id=x的数据,则查询过程:
  1. 取出根节点(根磁盘块),获得40和60两个关键字
  2. 如果x<40,则走P1;如果x=40,则命中;如果40<x<60,则走P2;如果x=60,则命中;如果x>60,则走P3.
  3. 根据以上规则命中后,加载对应的数据,数据区中存储的是具体的数据或者是指向数据的指针。

注:
每次新增、删除、修改数据导致关键字变化时,B-Tree为了保证树的平衡,会导致树结构发生很大的变化,这个过程是特别浪费时间的,所以创建索引需要谨慎。

B+Tree

B+Tree是在B-Tree基础上进行优化得到的。
B+Tree一个节点中包含的内容:
在这里插入图片描述

B+Tree对于IO性能的优化和B-Tree一样,B+Tree同样每个节点中存放多条记录数据(多个关键字),但是每个节点的关键字数=路数(指针数)
B+Tree中间节点中没有数据区,所有的数据区都在叶子节点中。
叶子节点中的指针指向下一个叶子节点,构成有序的链表结构。
在这里插入图片描述
如果要从上图中查找id=1的数据,则查询过程:

  1. 取出根节点(根磁盘块),获得1、28、66三个关键字
  2. 如果id<=1,则走P1,获得1、10、20三个关键字
  3. 如果id<=1,则走P1,获得1、8、9三个关键字
  4. 已经到达叶子节点,命中1,加载对应的数据,数据区中存储的是具体的数据或者是指向数据的指针。

mysql为什么要用B+Tree,不要B-Tree?

  1. 减少IO次数,提高效率
    因为B+Tree中间节点中没有数据区,所以对于同样大小的节点,B+Tree可以有更多的记录数,因此B+Tree的层数会更少,IO次数也就会更少。
  2. B+Tree的查询效率稳定
    因为B+Tree的数据都放在叶子节点,所以查询复杂度稳定为树高;B-Tree的查询时间复杂度在1到树高之间(分别对应记录在根节点和叶节点)。
  3. 更适于范围查询
    对于范围查询,B+Tree只需要遍历所有叶子节点;B-Tree首先找到要查找的下限,然后对B-Tree进行中序遍历,直到找到查找的上限。

B+Tree劣势
由于关键字会重复出现,因此会占用更多的空间。但是与带来的性能优势相比,空间劣势往往可以接受。

索引的种类

索引
聚集索引
非聚集索引
主键索引
普通索引
唯一索引
组合索引
全文索引
  • 聚集索引
    对于mysql,在建表时,就会以主键创建聚集索引;如果没有主键,则选择一个非空的唯一索引作为聚集索引;都没有则隐式生成一个主键创建聚集索引。一张表只有一个聚集索引。
    记录的所有数据都会放在聚集索引的叶子节点中。
  • 主键索引
    mysql的主键索引就是聚集索引。
  • 非聚集索引
    除了聚集索引都是非聚集索引。
  • 普通索引
    没有任何限制的索引。
  • 唯一索引
    索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。
  • 组合索引
    在多个字段上创建索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。使用组合索引时遵循最左原则。
  • 全文索引
    主要用来查找文本中的关键字,而不是直接与索引中的值相比较。

注:

  1. 非聚集索引的查询过程
    非聚集索引的节点中存有建立索引的字段值、主键值。针对上文建立的user表,对name字段加上非聚集索引,select name,age from user where name = '张三',对于这条sql,当使用非聚集索引查询时,命中非聚集索引某节点后,会再根据主键值到聚集索引中查询具体的age值;select name from user where name = '张三',对于这条sql,当使用非聚集索引查询时,命中非聚集索引某节点后,就直接返回name值即可。同理,如果对name、age加上组合索引,select name,age from user where name = '张三',当命中某节点后,也可以直接返回name、age值即可。

  2. 组合索引的最左前缀原则
    最左优先,以最左边的字段为起点任何连续的查询条件都能使用组合索引。所以应该将最经常用来查询的字段放在最左边。关于索引的最左前缀原则

问题

1、多个单列索引和联合索引的区别

参考多个单列索引和联合索引的区别详解

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值