MySQL数据库索引(中)
上一篇回顾:
1.一个索引对应一颗B+树,所有的真实记录都是存在叶子节点里面的,所有的项目录都存在内节点或者说根节点上。
2.innodb会为我们的表格主键添加一个聚簇索引,如果没有主键的话数据库是会为我们自动添加row_id这一列的。聚簇索引的叶子节点包含完整的用户记录。
3.我们是可以为自己感兴趣的列添加二级索引的,二级索引的叶子节点没有用户完整的信息,只是拥有对应列和主键的信息,如果想要拥有完整的信息是需要进行回表操作用二级索引找到的主键去聚簇索引寻找完整信息。
4.B+树的每一层节点都是按照索引列的大小信息进行排序而组成的双向链表,每个页里里面的记录也是按照索引列大小信息组成的单向链表。如果是联合索引的话,先按照前面的列进行排序,如果是相同的情况下再根据其他的列进行排序。
5.每个索引的搜索都是从根节点进行的,由于每个页面都按照索引列的值建立了Page Directory,所以在确定了具体页面信息的情况下是可以根据二分法进行快速的定位的。
索引的代价:
1.空间上的代价:每一个索引对应的都是一颗B+树,B+树的每一个节点都对应的是一个16kb大小的数据页,如果是一个很大的数据库的话那么占用的内存还是很大的。
2.时间上的代价:我们在上面讲过,每层节点都是按照数据的大小顺序进行排列的单向链表,每个页也是按照大小排列的双向链表。那么我们在对数据进行操作的时候必然避免不了的就是数据的迁移,数据页的删除,回收,分裂等等,如果我们创建的索引过多的话那么对应的问题就是频繁的需要对这些东西进行操作。那就是浪费时间,给性能拖后腿。
B+树适用的范围:
1:创建一个我们这篇文章需要用到的数据表:
我们创建好表格以后需要注意的问题:
1>我们是没有主键的,那么是由数据库给我们生成主键,然后再根据主键创建聚簇索引;
2>我们自己创建的索引是没有包含country这个列的,所以我们索引的叶子节点只包含name,birthday,phon_num的值以及数据库帮助我们创建的主键row_id;
下面我们给出的就是这个索引的示意图:我们用颜色对内节点以及叶子节点进行了区分,而且我们必须要注意的就是这是根据name先排序,然后再根据birthday、phon
全值匹配:
如果是我们进行查询的数据列和我们索引所有列的顺序都是一样的话,那么我们称之为全值匹配,如下所示的查询:
我们就可以利用索引进行快速的确定name=asiz的位置,然后如果有相同数据的话再根据这个信息进行birthday和phon_num的匹配。因为我们的索引是现根据name进行排序,再根据birthday和phon_num进行的排序。
但是,如果我们要是改变了这个顺序,首先使用birthday进行查询的话,那么就是不能使用这个索引,只能全文检索了。因为我们的索引都是先根据name进行排序的。
所以我们在使用联合索引的时候必须要严格按照顺序,至于里面具体的规则我们下面在讲。
匹配最左边的列:
1>只包含最左边的一个列:如下图所示,这样也是可以使用到我们的联合索引的
2>包含左边的多个列:如下图所示,这样操作也是没问题的
3>如果我们在查询的时候没有使用到最左边的name列,如下图所示,这是不能使用索引的,只能进行全文的检索
注意:
所以我们在使用联合索引的时候,务必需要记住的就是一定要使用到第一个列,因为我们的索引就是按照第一个列最先开始排序的,如果不按照这个规则进行,那么我们是不能使用到索引的。而且,就如我们最后一条查询而言,我们在进行完成name的索引以后,在相同情况下进行phon_num的查询的时候是不能使用索引的,因为name完成以后是根据birthday进行的索引排序,所以一定要严格按照索引定义的顺序进行查找。
匹配值前缀:
1>如果我们在进行字符串的搜素的时候是没有必要输入完整的字符串的,就好像我们的模糊查询,我们只需要输入字符串的前面字母即可得到筛选的结果,因为B+树是现根据name进行排序的,我们只使用前面的部分字符也是可以进行二分查找迅速定位。
2>如果我们给定的字符是位于字符串中间,那么这样是不可行的,是不能使用索引的,只能进行全文的检索,如下图所示:
范围匹配:
1>我们的索引也是可以应用在范围查询里面的,如下图所示,因为我们的数据都是在页内按照单向链表进行排列,页之间是按照双向链表进行排列,所以是可以很快速获取到我们需要的数据:
2>但是我们在使用多个列的范围查找的时候我们只能使用到的是第一列的索引,但是其他列的索引我们是使用不到的,因为我们是根据查询出来的结果在不同的name里面在进行birthday的筛选,索引是根据相同name的条件下才对birthday进行排序的,如下图所示:
精确匹配某一列并范围匹配某一列:
对于同一个索引来说,我们使用多个列的范围查询的时候,只能使用最左边列的B+树,其他列是不能使用的。但是我们左边使用的是精确查询,右边使用的是范围查询,那么,我们的右边也是可以使用到B+树的,如下图所示:
我们分析一下上图:
1>第一部分的name进行的精确匹配当然是可以使用到索引的
2>因为我们name是一样的,和索引的排序规则一致,所以birthday的范围搜索也是可以使用到B+树的
3>因为birthday的范围进行不同查找的结果,所以我们在进行phon_num的查找的时候是不能使用B+树的。
用于排序:
我们在使用排序比如说Order by的时候也是可以使用到索引的,如下图所示,具体的规则和我们进行查询的时候是一样的,因为我们索引就是按照顺序已经进行好排序的,所以如果我们的排序的顺序和索引的顺序是一致的,那么完全没问题可以直接取用数据,但是就是一直强调的问题,如果我们列的顺序改变了们就不能在使用B+树了。
用于分组:
如下所示,我们在使用group by的时候需要进行分组,这个过程包含了三个部分,第一个是先对name一致的进行分组,第二个在着基础上在对birthday一致的进行分组,然后最后在基础上对phon_num一致的进行分组。这就正好和我们的索引是一致的,所以是可以使用到B+树的,和上面一样,我们的顺序问题是坚决的不能乱的。
索引的挑选:
1>必须条件:只为我们使用到的查询条件,分组,排序列创建索引。查询列表里面的列我们没有必要建立索引。
2>基数考虑:如果一个列的差异数据不是很多,我们称之为基数小的列。也就是说所有数据的这个列的数据大部分都相同,那么就是基数小,这种列没必要创建索引。
3>数据类型:我们知道的是索引列可以有很多的数据类型,比如说整形数据我们就有TINYINT、MEDIUMINT
、INT
、BIGINT
,它们所占用的空间内存肯定是不一样的,所以我们挑选数据类型小的类型作为索引列的数据类型,可以有效的节约空间,储存更多的数据,那么我们在进行数据取用的时候一次可以加载更多的数据进入内存,减小IO损耗,同时在CPU层次来说,数据类型越小,查询处理的速度是越快的。
4>索引字符串的前缀:这个问题我们在上面其实提到过,我们在使用索引的时候是可以的,那么在创建索引的时候当然也是可以的,这样可以减少很多的内存空间,e而且我们在做字符串比较的时候如果我们使用的是前缀那么比较的时间也是可以大大进行缩短的。具体的语法如下:
5>尽量使用联合索引:因为我们的每一个索引对应的都是一颗B+树,需要使用时间和空间进行维护的,我们文章开始就说了索引需要付出的代价。我们使用联合索引,是可以满足很多字段的索引条件的。
6>主键插入的顺序:记不记得我们在上边说的,索引的一个目录项对应的是一个页,我们的数据都是有序的进行单向链表的维护,那么如果我们的主键在后期插入中间的话就涉及到了位置的移动,目录项的修改,页面分裂,数据迁移等等问题。所以我们建议的是让数据库给主键进行自增生成。
7>避免冗余重复的索引:不要为一个列重复的添加多个索引,这样是不好的,他对效率的提升没有半点的帮助,但是对空间的消耗确实实打实的。
8>覆盖索引:比如我们开始创建的索引是没有包含country这个列的,如果我们如下图所示进行查询,我们本来是可以在索引直接得到三个列的数据,但是差一个列,这时候就必须用主键去聚簇索引进行回表操作了。所以我们查询的列最好都是我们索引的列,也就是说我们是鼓励把需要查询的列明确进行书写的。
MySQL数据库索引(中)的更多相关文章
- MySQL数据库索引的4大类型以及相关的索引创建
以下的文章主要介绍的是MySQL数据库索引类型,其中包括普通索引,唯一索引,主键索引与主键索引,以及对这些索引的实际应用或是创建有一个详细介绍,以下就是文章的主要内容描述. (1)普通索引 这是最基本 ...
- B树在数据库索引中的应用剖析
引言 关于数据库索引,google一个oracle index,mysql index总 有大量的结果,其中很多的使用方法推荐,**索引之n条经典建议云云.笔者认为,较之借鉴,在搞清楚了自己的需求的基 ...
- (转)MySql数据库索引原理(总结性)
本文引用文章如链接: http://www.codinglabs.org/html/theory-of-mysql-index.html#more-100 参考书籍:Mysql技术内幕 本文主要是阐述 ...
- 知识点:Mysql 数据库索引优化实战(4)
知识点:Mysql 索引原理完全手册(1) 知识点:Mysql 索引原理完全手册(2) 知识点:Mysql 索引优化实战(3) 知识点:Mysql 数据库索引优化实战(4) 一:插入订单 业务逻辑:插 ...
- 为什么MySQL数据库索引选择使用B+树?
在进一步分析为什么MySQL数据库索引选择使用B+树之前,我相信很多小伙伴对数据结构中的树还是有些许模糊的,因此我们由浅入深一步步探讨树的演进过程,在一步步引出B树以及为什么MySQL数据库索引选择使 ...
- MySQL数据库索引之B+树
一.B+树是什么 B+ 树是一种树型数据结构,通常用于数据库和操作系统的文件系统中.B+ 树的特点是能够保持数据稳定有序,其插入与修改操作拥有较稳定的对数时间复杂度.B+ 树元素自底向上插入,这与二叉 ...
- 第二百八十八节,MySQL数据库-索引、limit分页、执行计划、慢日志查询
MySQL数据库-索引.limit分页.执行计划.慢日志查询 索引,是数据库中专门用于帮助用户快速查询数据的一种数据结构.类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置,然后直接获 ...
- 程序员的算法课(16)-B+树在数据库索引中的作用
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m0_37609579/article/de ...
- MySQL数据库索引常见问题
笔者看过很多数据库相关方面的面试题,但大多数答案都不太准确,因此决定在自己blog进行一个总结. Q1:数据库有哪些索引?优缺点是什么? 1.B树索引:大多数数据库采用的索引(innoDB采用的是b+ ...
- 谈谈MySQL数据库索引
在分析MySQL数据库索引之前,很多小伙伴对数据结构中的树理解不够深刻.因此我们由浅入深一步步探讨树的演进过程,再一步步引出MySQL数据库索引底层数据结构. 一.二叉树 二叉查找树也称为有序二叉查找 ...
随机推荐
- C# 构建S7服务器 西门子的虚拟服务器 测试通讯 HslCommunication应用
本文将使用一个gitHub开源的组件技术来实现S7服务器的功能,使用的是基于以太网的TCP/IP实现,不需要额外的组件 github地址:https://github.com/dathlin/HslC ...
- chapter02 PCA主成分分析在手写数字识别分类的应用
#coding=utf8 # 导入numpy工具包. import numpy as np # 导入pandas用于数据分析. import pandas as pd from sklearn.met ...
- 记一次MSSQL到MySQL大数据迁移过程
工作中遇到一个需求 要将MSSQL数据库中共计12张表的数据大概1000W行数据迁移到MySQL数据库中,去年另一个同事负责这件事情,他采用的方法是先将MSSQL数据库里的数据生成同MySQL数据库表 ...
- CTF-练习平台-Misc之 多种方法解决
五.多种方法解决 题目提示:在做题过程中你会得到一个二维码图片 下载文件后解压发现是一个exe文件,打开后报错:将文件后缀名改为txt打开后发现是base64编码 联系到提示说最后是一个二维码,将它转 ...
- mongo dos操作
https://www.cnblogs.com/beileixinqing/p/8241822.html 基础1 https://blog.csdn.net/superjunjin/article/d ...
- Windows环境下用jwplayer+Nginx搭建视频点播服务器
flv视频可以采用两种方式发布: 一.普通的HTTP下载方式 二.基于Flash Media Server或Red5服务器的rtmp/rtmpt流媒体方式. 多数知名视频网站都采用的是前一种方式. 两 ...
- 获取js 文件传递的参数并使用json2进行json数据转换
主要的技术就不用详细进行介绍了,就是使用js文件进行参数的传递,用途有一下几个: 1,进行js的版本控制. 2,获取参数并,进行一些额外功能的添加(比如使用js 进行用户验证,设计开发API (一些开 ...
- tomcat源码阅读之StandardContext
Context实例表示一个具体的web应用程序,其中包含一个或者多个Wrapper实例,每个Wrapper表示一个具体的servlet定义.StandardContext类是Context接口的标准实 ...
- 【转】每天一个linux命令(52):ifconfig命令
原文网址:http://www.cnblogs.com/peida/archive/2013/02/27/2934525.html 许多windows非常熟悉ipconfig命令行工具,它被用来获取网 ...
- stylus 知识点
循环的范围可以用两个小数点..表示,如(1..10)就是从1到10,并且包括1和10 for in 的循环范围写法: for index in 1 2 3 等价于: $li_length = 3 fo ...