mysql的索引及其介绍总结(浅析MysQL B-Tree 索引)
mysql的索引及其介绍总结
浅析MysQL B-Tree 索引B-Tree 索引
不同的存储引擎也可能使用不同的存储结构,i如,NDB集群存储引擎内部实现使用了T-Tree结构存储这种索引,即使其名字是BTREE;InnoDB使用的是B+Tree。
B-Tree通常一位这所有的值都是按顺序存储的,并且每一个叶子页道根的距离相同。下图大致反应了InnoDB索引是如何工作的。
为什么mysql索引要使用B+树,而不是B树,红黑树
看完上面的文章就可以理解为何B-Tree索引能够快速访问数据了。因为存储引擎不再需要进行全表扫描获取需要的数据,叶子节点包含了所有元素信息,每一个叶子节点指针都指向下一个节点,所以很适合查找范围数据。
索引对多个值进行排列的依据是CREATE TABLE 语句中定义索引时的顺序。
那么,索引排序的规则就是按照 last_name ,first_name ,dob 的顺序来的。
可以使用 B-Tree 索引的查询类型
B-Tree索引适用于全键值、键值范围或键前缀查找。
键前缀查找只是用于根据最左前缀查找。
举个粒子:
|
CREATE TABLE People ( last_name VARCHAR ( 50 ) NOT NULL , first_name VARCHAR ( 50 ) NOT NULL , dob date NOT NULL , gender enum ( 'm' , 'f' ) NOT NULL , KEY ( last_name, first_name, dob ) ); |
这个表的索引如下:
type结果
type结果值从好到坏依次是:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
一般来说,得保证查询至少达到range级别,最好能达到ref,否则就可能会出现性能问题。
possible_keys:sql所用到的索引
key:显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL
(1)全值匹配
全值匹配指的是和索引中的所有列进行匹配。
例如上面的People表的索引(last_name,first_name,dob)可以用于查找last_name='Cuba Allen',first_name='Chuang',dob='1996-01-01'的人。这就是使用了索引中的所有列进行匹配,即全值匹配。
|
mysql> EXPLAIN select * from People where last_name = 'aaa' and first_name = 'bbb' and dob= '2020-11-20' \G; *************************** 1. row *************************** id: 1 select_type: SIMPLE table : People partitions: NULL type: ref possible_keys: last_name key : last_name < -----可以看到这个key就是我们定义的索引 key_len: 307 ref: const,const,const rows : 1 filtered: 100.00 Extra: NULL 1 row in set , 1 warning (0.00 sec) ERROR: No query specified |
(2)匹配最左前缀
可以只使用索引的第一个列进行匹配。
例如可以用于查找last_name='aaa'的人,即用于查找姓为Zeng的人,这里只使用了索引的最左列进行匹配,即匹配最左前缀。
|
mysql> EXPLAIN select * from People where last_name = 'aaa' \G; *************************** 1. row *************************** id: 1 select_type: SIMPLE table : People partitions: NULL type: ref possible_keys: last_name key : last_name < ----使用了索引 key_len: 152 ref: const rows : 3 filtered: 100.00 Extra: NULL 1 row in set , 1 warning (0.00 sec) ERROR: No query specified |
(3)匹配列前缀
可以只匹配某一列的值的开头部分。
例如可以用于查找last_name LIKE ‘a%'的人,即用于查找所有以Z开头的姓的人,这里只使用了索引最左列的前缀进行匹配,即匹配列前缀。
|
mysql> EXPLAIN select * from People where last_name = 'a%' \G; *************************** 1. row *************************** id: 1 select_type: SIMPLE table : People partitions: NULL type: ref possible_keys: last_name key : last_name < ---使用了索引 key_len: 152 ref: const rows : 1 filtered: 100.00 Extra: NULL 1 row in set , 1 warning (0.00 sec) ERROR: No query specified |
(4)匹配范围值
可以只适用索引的第一列查找符合某个范围内的数据。
例如可以用于查找last_name BETWEEN ‘aaa' AND ‘aaabbbccc'的人,即用于查找姓在aaa和aaabbbccc之间的人,这里只使用了索引最左列的前缀进行范围匹配,即匹配范围值。
|
mysql> EXPLAIN select * from People where last_name BETWEEN 'aaa' and 'aaabbbccc' \G; *************************** 1. row *************************** id: 1 select_type: SIMPLE table : People partitions: NULL type: range possible_keys: last_name key : last_name < ---使用了索引 key_len: 152 ref: NULL rows : 3 filtered: 100.00 Extra: Using index condition 1 row in set , 1 warning (0.00 sec) ERROR: No query specified |
(5)精确匹配某一列并范围匹配另外一列
可以使第一列全匹配,第二列范围匹配。
例如可以用于查找last_name='aaa' AND first_name LIKE 'b%'的人,即用于查找姓是Zeng,名字以C开头的人,这里使用了索引的最左列精确匹配,第二列进行范围匹配。
|
mysql> EXPLAIN select * from People where last_name = 'aaa' and first_name like 'b%' \G; *************************** 1. row *************************** id: 1 select_type: SIMPLE table : People partitions: NULL type: range possible_keys: last_name key : last_name < ---使用了索引 key_len: 304 ref: NULL rows : 1 filtered: 100.00 Extra: Using index condition 1 row in set , 1 warning (0.00 sec) ERROR: No query specified |
(6)只访问索引的查询
查询只需访问索引,而无须访问数据行。
例如select last_name, first_name where last_name='aaa'; 这里只查询索引所包含的last_name和first_name列,则无须读取数据行。
|
mysql> explain select last_name,first_name,dob from People where last_name = 'aaa' *************************** 1. row *************************** id: 1 select_type: SIMPLE table : People partitions: NULL type: ref possible_keys: last_name key : last_name key_len: 152 ref: const rows : 1 filtered: 100.00 Extra: Using index 1 row in set , 1 warning (0.00 sec) ERROR: No query specified |
B-Tree 的限制
(1)只能按照索引的最左列开始查找。
例如People表中的索引无法用于查找first_name为'bbb'的人,也无法查找某个特定生日的人,因为这两个列都不是最左数据列。
(2)只能按照索引最左列的最左前缀进行匹配。
例如People表中的索引无法查找last_name LIKE ‘%b'的人,虽然last_name就是此索引的最左列,但MySQL索引无法查找以‘b'结尾的last_name的记录。
(3)只能按照索引定义的顺序从左到右进行匹配,不能跳过索引中的列。
例如People表中的索引无法用于查找last_name='a' AND bod='1996-01-01'的人,因为MySQL无法跳过索引中的某一列而使用索引中最左列和排在末尾的列进行组合。如果不指定索引中中间的列,则MySQL只能使用索引的最左列,即第一列。
(4)如果查询中有某个列的范围查询,则其右边所有列都无法使用索引优化查找。
例如有这样一个查询:where last_name='a' AND first_name LIKE 'b%' AND dob='1996-01-01'; 这个查询只能使用索引的前两列,因为这里LIKE是一个范围条件,则first_name后面的索引列都将失效。(优化点:尽量不要在索引列中使用LIKE等范围条件,改用多个等于条件来替代,保证后面的索引列能生效。)
以上就是浅析MysQL B-Tree 索引的详细内容,更多关于MysQL B-Tree 索引的资料请关注开心学习网其它相关文章!
原文链接:https://segmentfault.com/a/1190000038243722?utm_source=tuicool&utm_medium=referral
- phpmysql完全学习手册教程(Windows下搭建PHP开发环境Apache+PHP+MySQL)
- mysqldump导入导出(MySQL官方导出工具mysqlpump的使用)
- php不能用mysql(php写入mysql中文乱码的实例解决方法)
- 阿里云mysql配置升级注意事项(详解如何在阿里云上安装mysql)
- mysql怎么删除用户操作(解决mysql删除用户 bug的问题)
- 查看mysql所有权限(MySQL 权限控制细节分析)
- mysql中使用show table status 查看表信息
- mysql数据类型
- 对mysql索引的理解(详解MySQL 8.0 之不可见索引)
- mysqlcount使用技巧(MySQL巧用sum、case和when优化统计查询)
- mysql高级概念(MySQL 自定义变量的概念及特点)
- myeclipse连接mysql数据库的方法(教你用eclipse连接mysql数据库)
- mysql一次查询的过程(一篇文章弄懂MySQL查询语句的执行过程)
- mysql数据库导入错误怎么处理(MySQL数据库导入导出数据之报错解答实例讲解)
- navicat连接mysql报错(解决Navicat Premium 连接 MySQL 8.0 报错"1251"的问题分析)
- mybatis为什么还用mysql(关于MyBatis连接MySql8.0版本的配置问题)
- 刚红就耍大牌,《琉璃》角色滤镜碎一地,心疼工作人员(琉璃角色滤镜碎一地)
- 袁冰妍郑业成这对可以处,有脸红情话他们是真的敢说(袁冰妍郑业成这对可以处)
- 《祝卿好》台词又土又甜,就喜欢这么直接的恋爱(祝卿好台词又土又甜)
- 大女主 汤唯垂青电视圈,搭档朱亚文出演《大明皇妃孙若微传》(汤唯垂青电视圈)
- 红色代表什么(红色代表什么情感和含义)
- 高中数学题(高中数学题型总结及解题方法)
热门推荐
- laravel事务状态(laravel dingo API返回自定义错误信息的实例)
- php依赖注入对象注册(php依赖注入知识点详解)
- dedecms代码在哪里(dedecms 解决rss相对路径问题)
- jquery无缝滚动代码(jQuery实现表格行数据滚动效果)
- Forms.Timer、Timers.Timer、Threading.Timer的区别
- 微信小程序即时聊天功能怎么实现(微信小程序实现聊天室功能)
- pythondatetime库详解(python使用time、datetime返回工作日列表实例代码)
- 常见的.NET面试题及推荐答案(一)
- 安装hbase1.1.2(Vmware + Ubuntu18.04 安装 Hbase 2.3.5的详细教程)
- css图片设置垂直居中(CSS居中实例之大小不固定的图片居中方法)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9