mysql 索引B-Tree类型对索引使用的生效和失效情况详解

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:

   当人们谈论索引的时候,如果没有特别指明类型 ,那多半说的是 B-Tree 索引,它使用B-Tree数据结构来存储数据。大多数 MySQL引擎都支持这种索引 。Archive引擎是 一个例外 :5.1 之前 Archive 不支持任何索引 ,直到 5.1 才开始支持单个自增列 ( A UTO INCREMENT ) 的索引。

我们使用术语"B-Tree ” ,是因为 MySQL 在 CREATE TABLE 和其他语句中也使用该关键字 。

  不过,底层的存储引擎也可能使用不同的存储结构,例如,NDB集群存储引擎内部实际上使用了T-Tree结构存储这种索引,即使其名字是BTREE1InnoDB则使用的是B+Tree,各种数据结构和算榕的变种不在本书的讨论范围之内。存储引擎以不同的方式使用B-Tree索引,性能也各有不同,各有优劣。例如,MyISAM使用前缀压缩技术使得索引更小,但InnoDB则按照原数据格式进行存储。再如MyISAM索引通过数据的物理位置引用被索引的行,而InnoDB则根据主键引用被索引的行。B-Tree通常意味着所有的值都是按顺序存储的,井且每一个叶子页到根的距离相同。图5-l展示了B-Tree索引的抽象表示,大致反映了InnoDB索引是如何工作的。MyISAM使用的结构有所不同,但基本思想是类似的。

blob.png

  B-Tree索引能够加快访问数据的速度,因为存储引擎不再需要进行全表扫描来获取需要的数据,取而代之的是从索引的根节点(图示并未画出)开始进行搜索。根节点的槽中存放了指向子节点的指针,存储引擎根据这些指针向下层查找。通过比较节点页的值和要查找的值可以找到合适的指针进入下层子节点,这些指针实际上定义了子节点页中值的上限和下限。最终存储引擎要么是找到对应的值,要么该记录不存在。


叶子节点比较特别,它们的指针指向的是被索引的数据,而不是其他的节点页(不同引擎的“指针”类型不同)。图5-1中仅绘制了一个节点和其对应的叶子节点,其实在根节点和叶子节点之间可能有很多层节点页。树的深度和表的大小直接相关。


B-Tree对索引列是顺序组织存储的,所以很适合查找范围数据。例如,在一个基于文本域的索引树上,按字母顺序传递连续的值进行查找是非常合适的,所以像“找出所有以I到K开头的名字”这样的查找效率会非常高。

假设有如下数据表:

1
2
3
4
5
6
7
CREATE  TABLE  People (
last_name  VARCHAR  (32)  NOT  NULL ,
first_name  VARCHAR  (32)  NOT  NULL ,
dob  date  NOT  NULL ,
gender enum ( 'm' 'f' NOT  NULL ,
KEY  (last_name, f irst_name, dob)
)

对于表中的每一行数据,索引中包含了last_name、first_name和dob列的值,图5-2显示了该索引是如何组织数据的存储的。

blob.png

请注意,索引对多个值进行排序的依据是四日.TETABLE语句中定义索引时列的顺序。看一下最后两个条目,两个人的姓和名都一样,则根据他们的出生日期来排列顺序。


可以使用B-Tree索引的查询类型。B-Tree索引适用于全键值、键值范围或键前缀查找其中键前缀查找只适用于根据最左前缀的查找。前面所述的索引对如下类型的查询有效。


全值匹配

全值匹配指的是和索引中的所有列进行匹配,例如前面提到的索引可用于查找姓名为CubaAllen、出生于1960-01-01的人。

匹配最左前级

前面提到的索引可用于查找所有姓为Allen的人,即只使用索引的第一列。匹配列前级也可以只匹配某一列的值的开头部分。例如前面提到的索引可用于查找所有以J开头的姓的人。这里也只使用了索引的第一列。

匹配范围值

例如前面提到的索引可用于查找姓在Allen和Barrymore之间的人。这里也只使用了索引的第一列。

精确匹配呆一列并范围匹配另一列

前面提到的索引也可用于查找所有姓为Allen,并且名字是字母K开头(比如Kim、Karl等)的人。即第一列last_name全匹配,第二列first_name范围匹配。

只访问索引的查询

B-Tree通常可以支持“只访问索引的查询”,即查询只需要访问索引,而无须访问数据行。后面我们将单独讨论这种“覆盖索引”的优化。


因为索引树中的节点是有序的,所以除了按值查找之外,索引还可以用于查询中的ORDERBY操作(按顺序查找)。一般来说,如果B-Tree可以按照某种方式查找到值,那么也可以按照这种方式用于排序。所以,如果0阳ERBY子句满足前面列出的几种查询类型,则这个索引也可以满足对应的排序需求。


下面是一些关于B-Tree索引的限制:


•如果不是按照索引的最左列开始查找,则无法使用索引。例如上面例子中的索引在每用于查找名字为Bill的人,也无怯查找某个特定生日的人,因为这两列都不是最左数据列。类似地,也无战查找姓氏以某个字母结尾的人。


•不能跳过索引中的列。也就是说,前面所述的索引无法用于查找姓为Smith并且在某个特定日期出生的人。如果不指定名(first_name),则MySQL只能使用索引的第一列。


•如果查询中有某个列的范围(like  between > < 都算范围查询)查询,则其右边所有列都无法使用索引优化查找。例如有查询 WHERE lastname='Smith’AND firstname like '%J%'AND dob=’1976-12-23',这个查询只能使用索引的前两列,因为这里的like是一个范围条件(但是服务器可以把其余列用于其他目的)。如果范围查询列值的数量有限,那么可以通过使用多个等于条件来代替范围条件。在本章的索引案例学习部分,我们将演示一个详细的案例。


到这里读者应该可以明白,前面提到的索引列的顺序是多么的重要:这些限制都和索引列的顺序有关。在优化性能的时候,可能需要使用相同的列但顺序不同的索引来满足不同类型的查询需求。


也有些限制并不是B-Tree本身导致的,而是MySQL优化器和存储引擎使用索引的方式导致的,这部分限制在未来的版本中可能就不再是限制了。


摘抄至《高性能MYSQL》

特别说明:尊重作者的劳动成果,转载请注明出处哦~~~http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt343
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
14天前
|
关系型数据库 MySQL 索引
mysql 分析5语句的优化--索引添加删除
mysql 分析5语句的优化--索引添加删除
12 0
|
20天前
|
存储 关系型数据库 MySQL
轻松入门MySQL:优化进销存管理,掌握MySQL索引,提升系统效率(11)
轻松入门MySQL:优化进销存管理,掌握MySQL索引,提升系统效率(11)
|
25天前
|
存储 自然语言处理 关系型数据库
ElasticSearch索引 和MySQL索引那个更高效实用那个更合适
ElasticSearch索引 和MySQL索引那个更高效实用那个更合适
37 0
|
26天前
|
SQL 存储 关系型数据库
MySQL not exists 真的不走索引么
MySQL not exists 真的不走索引么
24 0
|
29天前
|
SQL 存储 关系型数据库
对线面试官 - 如何理解MySQL的索引覆盖和索引下推
索引下推是MySQL 5.6引入的优化,允许部分WHERE条件在索引中处理,减少回表次数。例如,对于索引(zipcode, lastname, firstname),查询`WHERE zipcode=&#39;95054&#39; AND lastname LIKE &#39;%etrunia%&#39;`时,索引下推先过滤zipcode,然后在索引中应用lastname条件,降低回表需求。索引下推可在EXPLAIN的`Using index condition`中看到。
对线面试官 - 如何理解MySQL的索引覆盖和索引下推
|
14天前
|
SQL 缓存 关系型数据库
mysql性能优化-慢查询分析、优化索引和配置
mysql性能优化-慢查询分析、优化索引和配置
79 1
|
20天前
|
缓存 关系型数据库 MySQL
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
|
20天前
|
缓存 关系型数据库 MySQL
MySQL 查询优化:提速查询效率的13大秘籍(索引设计、查询优化、缓存策略、子查询优化以及定期表分析和优化)(中)
MySQL 查询优化:提速查询效率的13大秘籍(索引设计、查询优化、缓存策略、子查询优化以及定期表分析和优化)(中)
|
11天前
|
存储 关系型数据库 MySQL
【MySQL实战笔记】 04 | 深入浅出索引(上)-02
【4月更文挑战第9天】InnoDB数据库使用B+树作为索引模型,其中主键索引的叶子节点存储完整行数据,非主键索引则存储主键值。主键查询只需搜索一棵树,而非主键查询需两次搜索,因此推荐使用主键查询以提高效率。在插入新值时,B+树需要维护有序性,可能导致数据页分裂影响性能。自增主键在插入时可避免数据挪动和页分裂,且占用存储空间小,通常更为理想。然而,如果场景仅需唯一索引,可直接设为主键以减少查询步骤。
13 1
【MySQL实战笔记】 04 | 深入浅出索引(上)-02
|
13天前
|
关系型数据库 MySQL 数据库
6. 了解过Mysql的索引嘛 ?
了解MySQL的索引类型,包括单列索引(普通、唯一、主键和全文索引)和组合索引。单列索引用于一列,如普通索引允许重复值,唯一索引和主键索引不允许,后者不允许空值。全文索引适用于特定文本字段。组合索引是多列的,遵循左前缀原则,通常推荐用于提高查询效率,除非是主键。
12 0