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、MEDIUMINTINTBIGINT,它们所占用的空间内存肯定是不一样的,所以我们挑选数据类型小的类型作为索引列的数据类型,可以有效的节约空间,储存更多的数据,那么我们在进行数据取用的时候一次可以加载更多的数据进入内存,减小IO损耗,同时在CPU层次来说,数据类型越小,查询处理的速度是越快的。

4>索引字符串的前缀:这个问题我们在上面其实提到过,我们在使用索引的时候是可以的,那么在创建索引的时候当然也是可以的,这样可以减少很多的内存空间,e而且我们在做字符串比较的时候如果我们使用的是前缀那么比较的时间也是可以大大进行缩短的。具体的语法如下:

5>尽量使用联合索引:因为我们的每一个索引对应的都是一颗B+树,需要使用时间和空间进行维护的,我们文章开始就说了索引需要付出的代价。我们使用联合索引,是可以满足很多字段的索引条件的。

6>主键插入的顺序:记不记得我们在上边说的,索引的一个目录项对应的是一个页,我们的数据都是有序的进行单向链表的维护,那么如果我们的主键在后期插入中间的话就涉及到了位置的移动,目录项的修改,页面分裂,数据迁移等等问题。所以我们建议的是让数据库给主键进行自增生成。

7>避免冗余重复的索引:不要为一个列重复的添加多个索引,这样是不好的,他对效率的提升没有半点的帮助,但是对空间的消耗确实实打实的。

8>覆盖索引:比如我们开始创建的索引是没有包含country这个列的,如果我们如下图所示进行查询,我们本来是可以在索引直接得到三个列的数据,但是差一个列,这时候就必须用主键去聚簇索引进行回表操作了。所以我们查询的列最好都是我们索引的列,也就是说我们是鼓励把需要查询的列明确进行书写的。

原文地址:https://www.cnblogs.com/zslli/p/8946145.html

时间: 2024-08-30 16:02:45

MySQL数据库索引(中)的相关文章

B+树在mysql数据库索引中的使用

一:B-树是一种平衡的多路查找树,它在文件系统中很有用. 定义:一棵m 阶的B-树,或者为空树,或为满足下列特性的m 叉树: ⑴树中每个结点至多有m 棵子树. ⑵若根结点不是叶子结点,则至少有两棵子树. ⑶除根结点之外的所有非叶结点至少有[m/2] 棵子树: ⑷所有的非终端结点中包含以下信息数据:(n,A0,K1,A1,K2,-,Kn,An) 其中:n 为关键码的个数,Ki(i=1,2,-,n)为关键码且Ki<Ki+1,Ai 为指向子树根结点的指针(i=0,1,-,n),且指针Ai-1 所指子树

Mysql数据库索引

索引(Index)是帮助mysql高效获取数据的数据结构.对于高性能非常关键. 索引的重要性主要体现在数据量非常大的时候.规模小,负载轻的数据库即使没有索引也可以获到好的查询效果 例如: 1 mysql>select first_name from actor where actor_id=5; 改索引列位于actor_id列,因此mysql会使用索引找到actor_id为5的行. 索引有很多种类型,各自有各自的特点.索引实在存储引擎层实现的,而不是服务器层. (1).B-Tree索引 谈论引擎

第二百八十八节,MySQL数据库-索引

MySQL数据库-索引 索引,是数据库中专门用于帮助用户快速查询数据的一种数据结构.类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置,然后直接获取即可. 如果没有创建索引查找数据时,是全表扫描的,也就是向查字典一样没有目录,靠一页一页的翻到目标数据位置,这样如果数据量大会相当耗时, 索引就是快速帮助用户找到目标数据,节省时间 索引简介 索引是以B+tree方式的树形结构存放数据的 详情,可以网上搜索一下B+tree MySQL中常见索引有: 普通索引 唯一索引 主键索引 组合索

B树在数据库索引中的应用剖析(转载)

引言 关于数据库索引,随便Google一个Oracle index,Mysql index总有大量的结果出来,其中不乏某某索引之n条经典建议.笔者认为,较之借鉴,在搞清楚了自己的需求的基础上,对备选方案的原理有个尽可能深入全面的了解会更有利于我们的选择和决策.因为某种方案或者技术呈现出某种优势(包括可能没有被介绍到但一定存在的限制),不是定义出来的,而是因为其实现机制决定的.就像LinkedList和ArrayList分别适用于什么应用不是Document里面定义的,是由其本身的结构决定的.数据

php教程:MySql数据库索引原理

PHP教程有好几天都没有给大家带来关于PHP方面的知识啦,今天补上啊!本文这要讲述的是:MySql数据库索引原理,希望能对大家带来帮助! 第一部分主要从数据结构及算法理论层面讨论MySQL数据库索引的数理基础. 第二部分结合MySQL数据库中InnoDB数据存储引擎中索引的架构实现讨论聚集索引.非聚集索引及覆盖索引等话题. 第三部分讨论MySQL中高性能使用索引的策略. 一.数据结构及算法理论 Innodb存储引擎实现索引的数据结构是B+树,下面介绍几种数据结构,一步步阐述为什么要使用B+树 1

如何正确合理的建立MYSQL数据库索引

如何正确合理的建立MYSQL数据库索引 索引是快速搜索的关键.MySQL索引的建立对于MySQL的高效运行是很重要的.下面介绍几种常见的MySQL索引类型. 在数据库表中,对字段建立索引可以大大提高查询速度.假如我们创建了一个 mytable表: CREATE TABLE mytable( IDINTNOT NULL, username VARCHAR(16) NOT NULL ); 我们随机向里面插入了10000条记录,其中有一条:5555, admin. 在查找username="admin

MySQL数据库------索引

MySQL数据库------索引 一.索引的介绍 数据库中专门用于帮助用户快速查找数据的一种数据结构.类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置吗,然后直接获取. 二 .索引的作用 约束和加速查找 三.常见的几种索引: 普通索引,唯一索引,主键索引(这几个都是单列) 联合索引(多列),比如:联合主键索引.联合唯一索引.联合普通索引 无索引和有索引的区别以及建立索引的目的 无索引: 从前往后一条一条查询有索引:创建索引的本质,就是创建额外的文件(某种格式存储,查询的时候,先

MySQL数据库索引常见问题

笔者看过很多数据库相关方面的面试题,但大多数答案都不太准确,因此决定在自己blog进行一个总结. Q1:数据库有哪些索引?优缺点是什么? 1.B树索引:大多数数据库采用的索引(innoDB采用的是b+树).能够加快访问数据的速度,尤其是范围数据的查找非常快.缺点是只能从索引的最左列开始查找,也不能跳过索引中的列,如果查询中有某个列用到了范围查询,则右边所有列都无法使用索引优化查找. 2.哈希索引:基于哈希表实现.在MySQL中,只有Memory引擎显式的支持哈希搜索.哈希查找的速度非常快,但哈希

使用Sqoop1.4.4将MySQL数据库表中数据导入到HDFS中

问题导读:         1.--connect参数作用? 2.使用哪个参数从控制台读取数据库访问密码? 3.Sqoop将关系型数据库表中数据导入HDFS基本参数要求及命令? 4.数据默认导入HDFS文件系统中的路径? 5.--columns参数的作用? 6.--where参数的作用? 一.部分关键参数介绍 参数介绍 --connect <jdbc-uri> 指定关系型数据库JDBC连接字符串 --connection-manager <class-name> 指定数据库使用的管

MySQL数据库索引的4大类型以及相关的索引创建

以下的文章主要介绍的是MySQL数据库索引类型,其中包括普通索引,唯一索引,主键索引与主键索引,以及对这些索引的实际应用或是创建有一个详细介绍,以下就是文章的主要内容描述. (1)普通索引 这是最基本的MySQL数据库索引,它没有任何限制.它有以下几种创建方式: 创建索引 CREATE INDEX indexName ON mytable(username(length)); 如果是CHAR,VARCHAR类型,length可以小于字段实际长度:如果是BLOB和TEXT类型,必须指定 lengt