mysql 索引B-Tree类型对索引使用的生效和失效情况详解
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt343
当人们谈论索引的时候,如果没有特别指明类型 ,那多半说的是 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使用的结构有所不同,但基本思想是类似的。

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显示了该索引是如何组织数据的存储的。

请注意,索引对多个值进行排序的依据是四日.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 索引B-Tree类型对索引使用的生效和失效情况详解的更多相关文章
- mysql中的字符串类型数据索引优化
摘自 "高性能mysql" 对于一些字符串类型较长的字段搜索时, 可以参考如下方法
- MySQL基础篇(03):系统和自定义函数总结,触发器使用详解
本文源码:GitHub·点这里 || GitEE·点这里 一.系统封装函数 MySQL 有很多内置的函数,可以快速解决开发中的一些业务需求,大概包括流程控制函数,数值型函数.字符串型函数.日期时间函数 ...
- PowerDesigner15在win7-64位系统下对MySQL 进行反向工程以及建立物理模型产生SQL语句步骤图文傻瓜式详解
1.安装PowerDesigner15.MySQL5.不详细讲解了.网上一大把.请各位亲参考去. 2.安MyODBC-standard-3.51.0.7-win.msi.mysql-connector ...
- Java类型中ParameterizedType,GenericArrayType,TypeVariabl,WildcardType详解
(1). 和反射+泛型有关的接口类型 java.lang.reflect.Type:java语言中所有类型的公共父接口 java.lang.reflect.ParameterizedType java ...
- 全网最详细的CentOS7里安装MySQL时出现No package mysql-server available错误的解决办法(图文详解)
不多说,直接上干货! 直接yum install mysql的话会报错,原因在于yum安装库里没有直接可以用的安装包,此时需要用到MariaDB了,MariaDB是MySQL社区开发的分支,也是一个增 ...
- Java的各类型数据在内存中分配情况详解
1. 有这样一种说法,如今争锋于IT战场的两大势力,MS一族偏重于底层实现,Java一族偏重于系统架构.说法根据无从考证,但从两大势力各自的社区力量和图书市场已有佳作不难看出,此说法不虚,但 ...
- (转)Mysql数据库之Binlog日志使用总结Linux下用户组、文件权限详解
Linux下用户组.文件权限详解 原文:http://blog.csdn.net/sdulibh/article/details/51566772 用户组 在linux中的每个用户必须属于一个组,不能 ...
- MySQL数据库锁机制之MyISAM引擎表锁和InnoDB行锁详解
转 http://blog.csdn.net/hsd2012/article/details/51112009 转 http://blog.csdn.net/e421083458/article/de ...
- 深入理解MySQL索引原理和实现——为什么索引可以加速查询?
说到索引,很多人都知道“索引是一个排序的列表,在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址,在数据十分庞大的时候,索引可以大大加快查询的速度,这是因为使用索引后可以不用扫描全表来定位某 ...
随机推荐
- 双向lstm-crf源码的问题和细微修改
别人的源码地址:https://github.com/chilynn/sequence-labeling/ 如果你训练就会发现loss降到0以下,按照他设定的目标函数,loss理论上应该是大于0的,仔 ...
- factorOne cannot be&nb…
factorOne cannot be resolved or is not a field 现象描述: Eclipse的使用时会在代码处出现警告factorOne cannot be resolve ...
- jQuery 去空
//去左右空格; function trim(s){ return s.replace(/(^\s*)|(\s*$)/g, ""); } //去掉字符串中所有空格(包括中间 ...
- ReactiveSwift源码解析(十) Lifetime代码实现
为了之后博客的进行,本篇博客我们就来聊一下ReactiveSwift框架中的Lifetime类的具体实现.从Lifetime这个名字中我们就这道,就是生命周期.在ReactiveSwift中使用Lif ...
- whatwg-fetch源码分析
fetch 是什么 XMLHttpRequest的最新替代技术 fetch优点 接口更简单.简洁,更加语义化 基于promise,更加好的流程化控制,可以不断then把参数传递,外加 async/aw ...
- 70. Climbing Stairs【leetcode】递归,动态规划,java,算法
You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb ...
- js的基础要点
javascript作为一种脚本语言可以放在html页面中任何位置,但是浏览器解释html时是按先后顺序的,所以前面的script就先被执行.比如进行页面显示初始化的js必须放在head里面,因为初始 ...
- 揭秘Socket与底层数据传输实现
揭秘socket 什么是socket?socket字面意思其实就是一个插口或者套接字,包含了源ip地址.源端口.目的ip地址和源端口.但是socket在那个位置呢 ,在TCP/IP网络的四层体系和OS ...
- C++中加const与不加const的区别
“常量”与“只读变量”的区别. 常量肯定是只读的,例如5, "abc",等,肯定是只读的,因为常量是被编译器放在内存中的只读区域,当然也就不能够去修改它. “只读变量”则是在内存中 ...
- AI类人工智能产品经理的丛林法则
AI是大家都很关注的领域,然而对于大部分想要入行的同学来讲,AI的算法技术门槛相对较高,让很多空有热血但是缺少数学背景的同学望而却步.不知道什么时候,可能是“人人都是产品经理”这个论调的影响,产品经 ...