当前位置:首页 > 编程技术 > 正文内容

B-Tree 索引类型详解

yc8882年前 (2023-02-26)编程技术648

B-Tree 索引类型详解

索引有很多种类型,可以为不同的应用场景提供更好的性能。在 MySQL 中,索引是在存储引擎层实现的。接下来重点介绍四种常见的索引类型:B-Tree 索引、哈希索引、空间数据索引(R-Tree)、全文索引。这部分内容分为上下两个小节,本小节重点介绍 B-Tree 索引。

1. B-Tree 索引

B-Tree 索引是最常见的索引之一,当大家在谈论索引的时候,如果没有特别说明,那多半说的就是 B-Tree 索引。在 MySQL 中,大多数的存储引擎都支持 B-Tree 索引。

1.1 存储结构

B-Tree 对索引列的值是按顺序存储的,并且每一个叶子页到根的距离相同。B-Tree 索引可以加快数据查找的速度,因为存储引擎不需要全表扫描来获取数据,只要从索引的根节点开始搜索即可。

以表 customer 为例,我们来看看索引是如何组织数据的存储的。

mysql> create table customer(
		 id int,
         last_name varchar(30),
		 first_name varchar(30),
		 birth_date date,
		 gender char(1),
		 key idx1_customer(last_name,first_name,birth_date)
     );

如图,对于表中的每行数据,索引包含了 last_name、first_name 和 birth_date 的值。

1.2 适合 B-Tree 索引的查询类型

全值匹配

和索引中的所有列进行匹配,如查找姓名为 George Bush、1960-08-08 出生的客户。

mysql> explain select * from customer where first_name='George' and last_name='Bush' and birth_date='1960-08-08'\G*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: customer
   partitions: NULL
         type: refpossible_keys: idx1_customer
          key: idx1_customer
      key_len: 190
          ref: const,const,const
         rows: 1
     filtered: 100.00
        Extra: NULL1 row in set, 1 warning (0.00 sec)

匹配最左前缀

只使用索引的第一列,如查找所有姓氏为 Bush 的客户:

mysql> explain select * from customer where last_name='Bush'\G*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: customer
   partitions: NULL
         type: refpossible_keys: idx1_customer
          key: idx1_customer
      key_len: 93
          ref: const
         rows: 1
     filtered: 100.00
        Extra: NULL1 row in set, 1 warning (0.00 sec)

匹配列前缀

只匹配某一列的值的开头部分,如查找所有以 B 开头的姓氏的客户,这里使用了索引的第一列:

mysql> explain select * from customer where last_name like 'B%'\G*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: customer
   partitions: NULL
         type: rangepossible_keys: idx1_customer
          key: idx1_customer
      key_len: 93
          ref: NULL
         rows: 1
     filtered: 100.00
        Extra: Using index condition1 row in set, 1 warning (0.00 sec)

匹配范围值

查找所有姓氏在 Allen 和 Bush 之间的客户,这里使用了索引的第一列:

mysql> explain select * from customer where last_name between 'Allen' and 'Bush'\G*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: customer
   partitions: NULL
         type: rangepossible_keys: idx1_customer
          key: idx1_customer
      key_len: 93
          ref: NULL
         rows: 1
     filtered: 100.00
        Extra: Using index condition1 row in set, 1 warning (0.00 sec)

精确匹配某一列,并范围匹配另一列

第一列全匹配,第二列范围匹配,如查找姓氏为 Bush,名字以 G 开头的客户:

mysql> explain select * from customer where last_name='Bush' and first_name like 'G'\G*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: customer
   partitions: NULL
         type: rangepossible_keys: idx1_customer
          key: idx1_customer
      key_len: 186
          ref: NULL
         rows: 1
     filtered: 100.00
        Extra: Using index condition1 row in set, 1 warning (0.00 sec)

只访问索引的查询

只需要访问索引即可获取数据,不需要回表访问数据行,这种查询也叫覆盖索引:

mysql> explain select last_name from customer where last_name='Bush'\G*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: customer
   partitions: NULL
         type: refpossible_keys: idx1_customer
          key: idx1_customer
      key_len: 93
          ref: const
         rows: 1
     filtered: 100.00
        Extra: Using index1 row in set, 1 warning (0.00 sec)

除了上述这些查询类型外,索引还可以用于 order by 排序操作,因为索引中的节点是有序的。如果 B-Tree 可以按照某种方式查找到数据,那么也可以按照这种方式进行排序。

1.3 B-Tree 索引的限制

如果不是按照索引的最左列开始查找数据,则无法使用索引。如查找名字为 George 的客户:

mysql> explain select * from customer where first_name='George'\G*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: customer
   partitions: NULL
         type: ALLpossible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 1
     filtered: 100.00
        Extra: Using where1 row in set, 1 warning (0.00 sec)

不能跳过索引的列。如查找姓氏为 Bush,生日为 1960-08-08 的客户,这种查询只能使用索引的第一列:

mysql> explain select * from customer where last_name='Bush' and birth_date='1960-08-08'\G*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: customer
   partitions: NULL
         type: refpossible_keys: idx1_customer
          key: idx1_customer
      key_len: 93
          ref: const
         rows: 1
     filtered: 100.00
        Extra: Using index condition1 row in set, 1 warning (0.00 sec)

如果查询中有某个列的范围查询,在其右边的列都无法使用索引进行查找数据。如查找姓氏为以 B 开头,名字为 George 的客户。这个查询只能使用第一列,因为 like 是一个范围查询:

mysql> explain select * from customer where last_name like 'B%' and first_name='George'\G;*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: customer
   partitions: NULL
         type: rangepossible_keys: idx1_customer
          key: idx1_customer
      key_len: 186
          ref: NULL
         rows: 1
     filtered: 100.00
        Extra: Using index condition1 row in set, 1 warning (0.00 sec)

2. 小结

本小节介绍了 B-Tree 索引的存储结构、适合 B-Tree 索引的查询类型和相关限制,从中我们可以看出,索引列的顺序非常重要。在某些应用场景,可能需要创建相同列,但顺序不同的索引,来满足性能的优化。


本站发布的内容若侵犯到您的权益,请邮件联系站长删除,我们将及时处理!


从您进入本站开始,已表示您已同意接受本站【免责声明】中的一切条款!


本站大部分下载资源收集于网络,不保证其完整性以及安全性,请下载后自行研究。


本站资源仅供学习和交流使用,版权归原作者所有,请勿商业运营、违法使用和传播!请在下载后24小时之内自觉删除。


若作商业用途,请购买正版,由于未及时购买和付费发生的侵权行为,使用者自行承担,概与本站无关。


本文链接:https://www.10zhan.com/biancheng/10607.html

标签: mysql
分享给朋友:

“B-Tree 索引类型详解” 的相关文章

【说站】laravel实现自定义404页面并给页面传值

【说站】laravel实现自定义404页面并给页面传值

以 laravel5.8 为例,虽然有自带的404页面,但太简单,我们更希望能自定义404页面,将用户留在站点。实现的方式很简单,将自定义的视图文件命名为 404.blade.php,并放到 reso...

【说站】Thymeleaf报错Error resolving template “XXX”

【说站】Thymeleaf报错Error resolving template “XXX”

修改了一下开源项目的目录结构访问突然报错Error resolving template “XXX”可能原因有如下三种:第一种可能:原因:在使用springboot的过程中,如果使用thymeleaf...

【说站】利用Webhook实现Java项目自动化部署

【说站】利用Webhook实现Java项目自动化部署

用webhook就能实现Java项目自动部署,其实原理很简单。费话不多说,直接往下看教程。1. 创建gitee仓库并初始化2. 在linux安装git3. 在宝塔的软件的商店里下载Webhook4....

【说站】电脑安装MySQL时出现starting the server失败原因及解决方案

【说站】电脑安装MySQL时出现starting the server失败原因及解决方案

今天在安装MySQL时出现starting the server失败,经过查询分析得出以下结论,记录一下操作步骤。原因分析:如果电脑是第一次安装MySQL,一般不会出现这样的报错。如下图所示。star...

【说站】vagrant实现linux虚拟机的安装并配置网络

【说站】vagrant实现linux虚拟机的安装并配置网络

一、VirtualBox的下载和安装1、下载VirtualBox官网下载:https://www.virtualbox.org/wiki/Downloads我的电脑是Windows的,所以下载Wind...

【说站】C#在PDF中添加墨迹注释Ink Annotation的步骤详解

【说站】C#在PDF中添加墨迹注释Ink Annotation的步骤详解

PDF中的墨迹注释(Ink Annotation),表现为徒手涂鸦式的形状;该类型的注释,可任意指定形状顶点的位置及个数,通过指定的顶点,程序将连接各点绘制成平滑的曲线。下面,通过C#程序代码介绍如何...