目录

一 索引原理

1. 循环遍历查找

2. 二分法查找

3. 有序数组  

4. 链表  

5. 二叉查找树  

6. 平衡二叉树(AVL树)  

7. B-树

8. b+树

二 MySQL存储引擎和索引

1 概念

2 查看命令

3 MyISAM和InnoDB对比

4 不同的存储引擎支持的索引类型也不一样

5.不同的存储引擎及特点

6. 聚集索引和非聚集索引

三 详细分析利用聚集索引查找数据

四 详细分析利用非聚集索引查找数据


一 索引原理

索引(Index)是帮助MySQL高效获取数据的数据结构。可以得到索引的本质:索引是排好序的快速查找数据结构。一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储在磁盘上。mysql内部索引是由不同的引擎实现的,主要是InnoDB和MyISAM这两种引擎,都是使用b+树的结构来存储的。

先了解几个概念

  • 扇区:磁盘存储的最小单位,扇区一般大小为512Byte。
  • 磁盘块:文件系统与磁盘交互的的最小单位(计算机系统读写磁盘的最小单位),一个磁盘块由连续几个(2^n)扇区组成,块一般大小一般为4KB。
  • 磁盘读取数据:磁盘读取数据靠的是机械运动,每次读取数据花费的时间可以分为寻道时间、旋转延迟、传输时间三个部分,寻道时间指的是磁臂移动到指定磁道所需要的时间,主流磁盘一般在5ms以下;旋转延迟就是我们经常听说的磁盘转速,比如一个磁盘7200转,表示每分钟能转7200次,也就是说1秒钟能转120次,旋转延迟就是1/120/2 = 4.17ms;传输时间指的是从磁盘读出或将数据写入磁盘的时间,一般在零点几毫秒,相对于前两个时间可以忽略不计。那么访问一次磁盘的时间,即一次磁盘IO的时间约等于5+4.17 = 9ms左右,听起来还挺不错的,但要知道一台500 -MIPS的机器每秒可以执行5亿条指令,因为指令依靠的是电的性质,换句话说执行一次IO的时间可以执行40万条指令,数据库动辄十万百万乃至千万级数据,每次9毫秒的时间,显然是个灾难。
  • mysql中的页:mysql中和磁盘交互的最小单位称为页,页是mysql内部定义的一种数据结构,默认为16kb,相当于4个磁盘块,也就是说mysql每次从磁盘中读取一次数据是16KB,要么不读取,要读取就是16KB,此值可以修改的。
  • 数据检索过程:我们对数据存储方式不做任何优化,直接将数据库中表的记录存储在磁盘中,假如某个表只有一个字段,为int类型,int占用4个byte,每个磁盘块可以存储1000条记录,100万的记录需要1000个磁盘块,如果我们需要从这100万记录中检索所需要的记录,需要读取1000个磁盘块的数据(需要1000次io),每次io需要9ms,那么1000次需要9000ms=9s,100条数据随便一个查询就是9秒,这种情况我们是无法接受的,显然是不行的。

我们迫切需要这样的数据结构和算法:

  1. 需要一种数据存储结构:当从磁盘中检索数据的时候能,够减少磁盘的io次数,最好能够降低到一个稳定的常量值

  2. 需要一种检索算法:当从磁盘中读取磁盘块的数据之后,这些块中可能包含多条记录,这些记录被加载到内存中,那么需要一种算法能够快速从内存多条记录中快速检索出目标数据。

1. 循环遍历查找

从一组无序的数据中查找目标数据,常见的方法是遍历查询,n条数据,时间复杂度为O(n),最快需要1次,最坏的情况需要n次,查询效率不稳定。

2. 二分法查找

二分法查找也称为折半查找,用于在一个有序数组中快速定义某一个需要查找的数据。二分查找速度是相当快的,每次查找都会使范围减半。对于有序数组[1,2,3,4,5,6,7,8,9],如果我们采用顺序查找,上面数据最快需要1次,最多需要9次,而二分法查找最多只需要3次,耗时时间也比较稳定。

二分法查找时间复杂度是:O(logN)(N为数据量),100万数据查找最多只需要20次(2^20=1048576‬)

二分法查找数据的优点:定位数据非常快,前提是:目标数组是有序的。

3. 有序数组  

如果我们将mysql中表的数据以有序数组的方式存储在磁盘中,那么我们定位数据步骤是:

  • 取出目标表的所有数据,存放在一个有序数组中
  • 如果目标表的数据量非常大,从磁盘中加载到内存中需要的内存也非常大

步骤1取出所有数据耗费的io次数太多,步骤2耗费的内存空间太大,还有新增数据的时候,为了保证数组有序,插入数据会涉及到数组内部数据的移动,也是比较耗时的,显然用这种方式存储数据是不可取的。

4. 链表  

链表相当于在每个节点上增加一些指针,可以和前面或者后面的节点连接起来,就像一列火车一样,每节车厢相当于一个节点,车厢内部可以存储数据,每个车厢和下一节车厢相连。

链表的优点:

  • 可以快速定位到上一个或者下一个节点
  • 可以快速删除数据,只需改变指针的指向即可,这点比数组好

链表的缺点:

  • 无法向数组那样,通过下标随机访问数据
  • 查找数据需从第一个节点开始遍历,不利于数据的查找,查找时间和无序数据类似,需要全遍历,最差时间是O(N)

5. 二叉查找树  

二叉树是每个结点最多有两个子树的树结构,通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。

数组[20,10,5,15,30,25,35]使用二叉查找树存储如下:

每个节点上面有两个指针(left,rigth),可以通过这2个指针快速访问左右子节点,检索任何一个数据最多只需要访问3个节点,相当于访问了3次数据,时间为O(logN),和二分法查找效率一样,查询数据还是比较快的。

但是如果我们插入数据是有序的,如[5,10,15,20,30,25,35],那么结构就变成下面这样:

二叉树退化为了一个链表结构,查询数据最差就变为了O(N)。

二叉树的缺点

查询数据的效率不稳定,若树左右比较平衡的时,最差情况为O(logN),如果插入数据是有序的,退化为了链表,查询时间变成了O(N)数据量大的情况下,会导致树的高度变高,如果每个节点对应磁盘的一个块来存储一条数据,需io次数大幅增加,显然用此结构来存储数据是不可取的。

6. 平衡二叉树(AVL树)  

平衡二叉树是一种特殊的二叉树,所以他也满足前面说到的二叉查找树的两个特性,同时还有一个特性:它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

平衡二叉树相对于二叉树来说,树的左右比较平衡,不会出现二叉树那样退化成链表的情况,不管怎么插入数据,最终通过一些调整,都能够保证树左右高度相差不大于1。这样可以让查询速度比较稳定,查询中遍历节点控制在O(logN)范围内。

如果数据都存储在内存中,采用AVL树来存储,还是可以的,查询效率非常高。不过我们的数据是存在磁盘中,用过采用这种结构,每个节点对应一个磁盘块,数据量大的时候,也会和二叉树一样,会导致树的高度变高,增加了io次数,显然用这种结构存储数据也是不可取的。

7. B-树

B杠树,B-树在是平衡二叉树上进化来的,前面介绍的几种树,每个节点上面只有一个元素,而B-树节点中可以放多个元素,主要是为了降低树的高度。一棵m阶的B-Tree有如下特性:

  1. 每个节点最多有m个孩子,m称为b树的阶
  2. 除了根节点和叶子节点外,其它每个节点至少有Ceil(m/2)个孩子
  3. 若根节点不是叶子节点,则至少有2个孩子
  4. 所有叶子节点都在同一层,且不包含其它关键字信息
  5. 每个非终端节点包含n个关键字(健值)信息
  6. 关键字的个数n满足:ceil(m/2)-1 <= n <= m-1
  7. ki(i=1,…n)为关键字,且关键字升序排序
  8. Pi(i=1,…n)为指向子树根节点的指针。P(i-1)指向的子树的所有节点关键字均小于ki,但都大于k(i-1)

B-Tree结构的数据可以让系统高效的找到数据所在的磁盘块。为了描述B-Tree,首先定义一条记录为一个二元组[key, data] ,key为记录的键值,对应表中的主键值,data为一行记录中除主键外的数据。对于不同的记录,key值互不相同。

B-Tree中的每个节点根据实际情况可以包含大量的关键字信息和分支,如下图所示为一个3阶的B-Tree:

每个节点占用一个盘块的磁盘空间,一个节点上有两个升序排序的关键字和三个指向子树根节点的指针,指针存储的是子节点所在磁盘块的地址。两个键将数据划分成的三个范围域,对应三个指针指向的子树的数据的范围域。以根节点为例,关键字为17和35,P1指针指向的子树的数据范围为小于17,P2指针指向的子树的数据范围为17~35,P3指针指向的子树的数据范围为大于35。

模拟查找关键字29的过程:

  1. 根据根节点找到磁盘块1,读入内存。【磁盘I/O操作第1次】

  2. 比较关键字29在区间(17,35),找到磁盘块1的指针P2

  3. 根据P2指针找到磁盘块3,读入内存。【磁盘I/O操作第2次】

  4. 比较关键字29在区间(26,30),找到磁盘块3的指针P2

  5. 根据P2指针找到磁盘块8,读入内存。【磁盘I/O操作第3次】

  6. 在磁盘块8中的关键字列表中找到关键字29

分析上面过程,发现需要3次磁盘I/O操作,和3次内存查找操作,由于内存中的关键字是一个有序表结构,可以利用二分法快速定位到目标数据,而3次磁盘I/O操作是影响整个B-Tree查找效率的决定因素。

B-树相对于avl树,通过在节点中增加节点内部数据的个数来减少磁盘的io操作。

上面我们说过mysql是采用页方式来读写数据,每页是16KB,我们用B-树来存储mysql的记录,每个节点对应mysql中的一页(16KB),假如每行记录加上树节点中的1个指针占160Byte,那么每个节点可以存储1000(16KB/160byte)条数据,树的高度为3的节点大概可以存储(第一层1000+第二层1000^2+第三层1000^3)10亿条记录,是不是非常惊讶,一个高度为3个B-树大概可以存储10亿条记录,我们从10亿记录中查找数据只需要3次io操作可以定位到目标数据所在的页,而页内部的数据又是有序的,然后将其加载到内存中用二分法查找,是非常快的。

可以看出使用B-树定位某个值还是很快的(10亿数据中3次io操作+内存中二分法),但是也是有缺点的:B-不利于范围查找,比如上图中我们需要查找[15,36]区间的数据,需要访问7个磁盘块(1/2/7/3/8/4/9),io次数又上去了,范围查找也是我们经常用到的,所以b-树也不太适合在磁盘中存储需要检索的数据。

8. b+树

先看个b+树结构图:

从图中可以看出,B+ 树中各个页之间是通过双向链表连接的,叶子节点中的数据是通过单向链表连接的。

b+树的特征

  1. 每个结点至多有m个子女
  2. 除根结点外,每个结点至少有[m/2]个子女,根结点至少有两个子女
  3. 有k个子女的结点必有k个关键字
  4. 父节点中持有访问子节点的指针
  5. 父节点的关键字在子节点中都存在(如上面的1/20/35在每层都存在),要么是最小值,要么是最大值,如果节点中关键字是升序的方式,父节点的关键字是子节点的最小值
  6. 最底层的节点是叶子节点
  7. 除叶子节点之外,其他节点不保存数据,只保存关键字和指针
  8. 叶子节点包含了所有数据的关键字以及data,叶子节点之间用链表连接起来,可以非常方便的支持范围查找

b+树与b-树的几点不同

  • b+树中一个节点如果有k个关键字,最多可以包含k个子节点(k个关键字对应k个指针);而b-树对应k+1个子节点(多了一个指向子节点的指针)
  • b+树非叶子结点存储关键字和指向子节点的指针,不存储数据;而b-树不仅存储关键字,还存储了数据,这样同样大小情况下,b+树可以存储更多的关键字。如果不存储数据,那么就会存储更多的键值,相应的树的阶数(节点的子节点树)就会更大,树就会更矮更胖,如此一来我们查找数据进行磁盘的 IO 次数又会再次减少,数据查询的效率也会更快。
  • b+树叶子节点中存储了所有关键字及data,并且多个节点用链表连接,从上图中看子节点中数据从左向右是有序的,这样快速可以支撑范围查找(先定位范围的最大值和最小值,然后子节点中依靠链表遍历范围数据)

二 MySQL存储引擎和索引

1 概念

在mysql中的数据用各种不同的技术存储 在文件(或内存)中。mysql内部索引是由不同的引擎实现的,用的最多的存储引擎有:innodb,myisam ,memory 等。其中,InnoDB和MyISAM这两种引擎中的索引都是使用b+树的结构来存储的,并且innodb支持事务,而myisam、memory等不支持事务。

2 查看命令

  • show engines;查看mysql支持的存储引擎。
  • show variables like ‘%storage_engine%’;  查看你的mysql当前默认的存储引擎

3 MyISAM和InnoDB对比

char和varchar都是用来存储字符串的,但是他们保持和检索的方式不同。

char是属于固定长度的字符类型,而varchar是属于可变长度的字符类型。

由于char是固定长度的所以它的处理速度比varchar快很多。但是缺点是浪费存储空间,读取char类型数据时候时如果尾部有空格会丢失空格,所以对于那种长度变化不大的并且对查询速度有较高要求的数据可以考虑使用char类型来存储。

不同的存储引擎对char和varchar的使用原则有所不同:

  • MyISAM存储引擎:建议使用固定长度的数据列代替可变长度的数据列。
  • MEMORY存储引擎:目前都使用固定长度的数据行存储,因此无论使用CHAR或VARCHAR列都没有关系。两者都是作为CHAR类型处理。
  • InnoDB存储引擎:建议使用VARCHAR类型。对于InnoDB数据表,内部的行存储格式没有区分固定长度和可变长度列(所有数据行都使用指向数据列值的头指针),因此在本质上,使用固定长度的CHAR列不一定比使用可变长度VARCHAR列性能要好。因而,主要的性能因素是数据行使用的存储总量。由于CHAR平均占用的空间多于VARCHAR,因此使用VARCHAR来最小化需要处理的数据行的存储总量和磁盘I/O是比较好的。

MyISAM和InnoDB对比

  1. InnoDB支持事务与外键和行级锁,MyISAM不支持(最主要的差别)
  2. MyISAM读性能要优于InnoDB,除了针对索引的update操作,MyISAM的写性能可能低于InnoDB,其他操作MyISAM的写性能也是优于InnoDB的,而且可以通过分库分表来提高MyISAM写操作的速度InnoDB是聚集索引,使用B+Tree作为索引结构,数据文件是和(主键)索引绑在一起的(表数据文件本身就是按B+Tree组织的一个索引结构),必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此,主键不应该过大,因为主键太大,其他索引也都会很大。MyISAM是非聚集索引,也是使用B+Tree作为索引结构,索引和数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。也就是说:InnoDB的B+树主键索引的叶子节点就是数据文件,辅助索引的叶子节点是主键的值;而MyISAM的B+树主键索引和辅助索引的叶子节点都是数据文件的地址指针。
  3. InnoDB 中不保存表的具体行数,也就是说,执行select count(*) from table时,InnoDB要扫描一遍整个表来计算有多少行,但是MyISAM只要简单的读出保存好的行数即可。注意的是,当count(*)语句包含 where条件时,两种表的操作是一样的。
  4. DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除。
  5. InnoDB表的行锁也不是绝对的,假如在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表,例如update table set num=1 where name like “%aaa%”,在where条件没有主键时,InnoDB照样会锁全表
  6. Innodb不支持全文索引,而MyISAM支持全文索引,在涉及全文索引领域的查询效率上MyISAM速度更快高;PS:5.7以后的InnoDB支持全文索引了
  7. InnoDB表必须有唯一索引(如主键)(用户没有指定的话会自己找/生产一个隐藏列Row_id来充当默认主键),而Myisam可以没有
  8. Innodb存储文件有frm、ibd,而Myisam是frm、MYD、MYI

Innodb:frm是表定义文件,ibd是数据文件

Myisam:frm是表定义文件,myd是数据文件,myi是索引文件

选择哪种搜索引擎,应视具体应用而定

①如果是读多写少的项目,可以考虑使用MyISAM,MYISAM索引和数据是分开的,而且其索引是压缩的,可以更好地利用内存。所以它的查询性能明显优于INNODB。压缩后的索引也能节约一些磁盘空间。MYISAM拥有全文索引的功能,这可以极大地优化LIKE查询的效率。

②如果你的应用程序一定要使用事务,毫无疑问你要选择INNODB引擎

③如果是用MyISAM的话,merge引擎可以大大加快应用部门的开发速度,他们只要对这个merge表做一些select count(*)操作,非常适合大项目总量约几亿的rows某一类型(如日志,调查统计)的业务表。

4 不同的存储引擎支持的索引类型也不一样

InnoDB 支持事务,支持行级别锁定,支持 B-tree、Full-text 等索引,不支持 Hash 索引;

MyISAM 不支持事务,支持表级别锁定,支持 B-tree、Full-text 等索引,不支持 Hash 索引;

Memory 不支持事务,支持表级别锁定,支持 B-tree、Hash 等索引,不支持 Full-text 索引;

NDB 支持事务,支持行级别锁定,支持 Hash 索引,不支持 B-tree、Full-text 等索引;

Archive 不支持事务,支持表级别锁定,不支持 B-tree、Hash、Full-text 等索引;

5.不同的存储引擎及特点

6. 聚集索引和非聚集索引

在 MySQL 中,B+ 树索引按照存储方式的不同分为聚集索引和非聚集索引。

非聚集索引(非聚簇索引)

非聚集索引以主键以外的列值作为键值构建的 B+ 树索引,我们称之为非聚集索引。非聚集索引的叶子节点不存储表中的数据,而是存储该列对应的主键,想要查找数据我们还需要根据主键再去聚集索引中进行查找,这个再根据聚集索引查找数据的过程,我们称为回表。

聚集索引(聚簇索引)

以 InnoDB 作为存储引擎的表,表中的数据都会有一个主键,即使你不创建主键,系统也会帮你创建一个隐式的主键。叶子节点存的是整行数据,直接通过这个聚集索引的键值找到某行 ,数据的物理存放顺序与索引顺序是一致的,即:只要索引是相邻的,那么对应的数据一定也是相邻地存放在磁盘上的。同时数据行和相邻的键值紧凑地存储在一起,因为无法同时把数据行存放在两个不同的地方,所以一个表只能有一个聚集索引。

MyISAM索引实现(非聚集的)

MyISAM引擎使用B+Tree作为索引结构,B+ 树索引的叶子节点并不存储数据,而是存储数据的文件地址。不管是主键索引还是辅助索引结构都是一样的,叶子节点保存了索引字段的值以及数据记录的地址。下图是MyISAM索引的原理图:

这里设表一共有三列,假设我们以Col1为主键,则图8是一个MyISAM表的主索引(Primary key)示意。可以看出MyISAM的索引文件仅仅保存数据记录的地址。在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复。如果我们在Col2上建立一个辅助索引,则此索引的结构如下图所示:

辅助索引同样也是一颗B+Tree,data域保存数据记录的地址。因此,MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其data域的值,然后以data域的值为地址,读取相应数据记录。

MyISAM的索引方式也叫做“非聚集”的,之所以这么称呼是为了与InnoDB的聚集索引区分。

InnoDB索引实现(聚集索引)

InnoDB 是把数据存放在 B+ 树中的,而 B+ 树的键值就是主键,在 B+ 树的叶子节点中,存储了表中所有的数据。这种以主键作为 B+ 树索引的键值而构建的 B+ 树索引,我们称之为聚集索引。

虽然InnoDB也使用B+Tree作为索引结构,但具体实现方式却与MyISAM截然不同。

第一个与MyISAM索引的不同是InnoDB的数据文件本身就是索引文件。MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。而在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。

上图是InnoDB主索引(同时也是数据文件)的示意图,可以看到叶节点包含了完整的数据记录。这种索引叫做聚集索引。因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。

第二个与MyISAM索引的不同是InnoDB的辅助索引data域存储相应记录主键的值而不是地址。换句话说,InnoDB的所有辅助索引都引用主键作为data域。例如,图11为定义在Col3上的一个辅助索引:

这里以英文字符的ASCII码作为比较准则。聚集索引这种实现方式使得按主键的搜索十分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。

了解不同存储引擎的索引实现方式对于正确使用和优化索引都非常有帮助,例如知道了InnoDB的索引实现后,就很容易明白为什么不建议使用过长的字段作为主键,因为所有辅助索引都引用主索引,过长的主索引会令辅助索引变得过大。再例如,用非单调的字段作为主键在InnoDB中不是个好主意,因为InnoDB数据文件本身是一颗B+Tree,非单调的主键会造成在插入新记录时数据文件为了维持B+Tree的特性而频繁的分裂调整,十分低效,而使用自增字段作为主键则是一个很好的选择。

我们用的最多的是innodb存储引擎,所以此处主要说一下innodb索引的情况,innodb中最好是采用主键查询,这样只需要一次索引,如果使用辅助索引检索,涉及到回表操作,比主键查询要耗时一些。

innodb中辅助索引为什么不像myisam那样存储记录的地址?

表中的数据发生变更的时候,会影响其他记录地址的变化,如果辅助索引中记录数据的地址,此时会受影响,而主键的值一般是很少更新的,当页中的记录发生地址变更的时候,对辅助索引是没有影响的。

三 详细分析利用聚集索引查找数据

现在假设我们要查找 id>=18 并且 id<40 的用户数据。对应的 sql 语句为:

select * from user where id>=18 and id <40

其中 id 为主键,具体的查找过程如下:

①一般根节点都是常驻内存的,也就是说页 1 已经在内存中了,此时不需要到磁盘中读取数据,直接从内存中读取即可。

从内存中读取到页 1,要查找这个 id>=18 and id <40 或者范围值,我们首先需要找到 id=18 的键值。

从页 1 中我们可以找到键值 18,此时我们需要根据指针 p2,定位到页 3。

②要从页 3 中查找数据,我们就需要拿着 p2 指针去磁盘中进行读取页 3。

从磁盘中读取页 3 后将页 3 放入内存中,然后进行查找,我们可以找到键值 18,然后再拿到页 3 中的指针 p1,定位到页 8。

③同样的页 8 页不在内存中,我们需要再去磁盘中将页 8 读取到内存中。

将页 8 读取到内存中后。因为页中的数据是链表进行连接的,而且键值是按照顺序存放的,此时可以根据二分查找法定位到键值 18。

此时因为已经到数据页了,此时我们已经找到一条满足条件的数据了,就是键值 18 对应的数据。

因为是范围查找,而且此时所有的数据又都存在叶子节点,并且是有序排列的,那么我们就可以对页 8 中的键值依次进行遍历查找并匹配满足条件的数据。

我们可以一直找到键值为 22 的数据,然后页 8 中就没有数据了,此时我们需要拿着页 8 中的 p 指针去读取页 9 中的数据。

④因为页 9 不在内存中,就又会加载页 9 到内存中,并通过和页 8 中一样的方式进行数据的查找,直到将页 12 加载到内存中,发现 41 大于 40,此时不满足条件。那么查找到此终止。

最终我们找到满足条件的所有数据,总共 12 条记录:

(18,kl), (19,kl), (22,hj), (24,io), (25,vg) , (29,jk), (31,jk) , (33,rt) , (34,ty) , (35,yu) , (37,rt) , (39,rt) 。

下面看下具体的查找流程图

四 详细分析利用非聚集索引查找数据

对于叶子节点中的 x-y,比如 1-1。左边的 1 表示的是索引的键值,右边的 1 表示的是主键值。

如果我们要找到幸运数字为 33 的用户信息,对应的 sql 语句为:

select * from user where luckNum=33

查找的流程跟聚集索引一样,这里就不详细介绍了。我们最终会找到主键值 47,找到主键后我们需要再到聚集索引中查找具体对应的数据信息,此时又回到了聚集索引的查找流程。

下面看下具体的查找流程图:

在 MyISAM 中,聚集索引和非聚集索引的叶子节点都会存储数据的文件地址。

参考链接

https://www.cnblogs.com/biao/p/11776898.html

http://www.liuzk.com/410.html

http://blog.codinglabs.org/articles/theory-of-mysql-index.html

MySQL索引原理和引擎相关推荐

  1. mysql json匹配key为数值_干货篇:一篇文章让你——《深入解析MySQL索引原理》

    概述 最近一段时间重新深入研究了一遍MySQL的内容,今天主要分享分析MySQL索引原理,后续会输出一些关于MySQL方面的干货,希望各位小伙伴喜欢. 一.什么是索引.为什么要建立索引? 关于索引的理 ...

  2. 知识点:Mysql 索引原理完全手册(1)

    知识点:Mysql 索引原理完全手册(1) 知识点:Mysql 索引原理完全手册(2) 知识点:Mysql 索引优化实战(3) 知识点:Mysql 数据库索引优化实战(4) Mysql-索引原理完全手 ...

  3. MySQL索引原理详解

    MySQL索引原理详解 索引的本质 索引的分类 Hash 索引 二叉树 B树(二三树) B+树 主键目录 索引页 索引页的分层 非主键索引 回表 索引的本质 索引的本质是一种排好序的数据结构. 索引的 ...

  4. (2)Mysql索引原理和优化总结

    Mysql设计原理栏目总结 (1)Mysql架构和常用引擎介绍 (2)Mysql索引原理和优化总结 1.索引理解和常见面试题 (1)本质 索引是一种能够高效获取数据的数据结构 索引存放在硬盘上 (2) ...

  5. mysql索引原理之聚簇索引

    索引分为聚簇索引和非聚簇索引. 以一本英文课本为例,要找第8课,直接翻书,若先翻到第5课,则往后翻,再翻到第10课,则又往前翻.这本书本身就是一个索引,即"聚簇索引". 如果要找& ...

  6. Mysql索引原理剖析与优化策略

    Mysql索引原理剖析与优化策略 1.索引的本质  在⽣产环境中,随着数据量不断的增⻓,SQL执⾏速度会越来越慢,常⻅的⼿段就是通过索引来提升查询速度,那么究竟为什么要添加索引?应该如何正确添加索引? ...

  7. 转:MySQL索引原理及慢查询优化

    来自:http://tech.meituan.com/mysql-index.html MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能出色, ...

  8. (转)MySQL索引原理及慢查询优化

    转自美团技术博客,原文地址:http://tech.meituan.com/mysql-index.html 建索引的一些原则: 1.最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到 ...

  9. 干货:MySQL 索引原理及慢查询优化

    转载自 http://blog.csdn.net/kaka1121/article/details/51815368 MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首 ...

最新文章

  1. iScience | 大规模表征学习寻找分子间相互作用
  2. 我们能达到电影里的智能吗?最可能实现的AI场景是什么?如何看待AI自主性?...
  3. 在线图表编辑工具 draw.io 10.6.2 版本发布
  4. C# MVC 使用 CKEditor图片上传 提示“不正确的服务器响应”
  5. java 里面write,java 中 System.out.println()和System.out.write()的区别
  6. 直播丨国产最强音:HTAP融合型分布式数据库EsgynDB架构详解
  7. Vi编辑器的基本使用方法及vi和Vim的区别【ZT】
  8. 华为云 EI 打造城市智能体,共筑数字政府基石
  9. 妙用chrome插件,实现U校园自动填答案
  10. 用于将 InfoPath 2007 集成到 Visual Studio 2005 中的 InfoPath Designer API 概述
  11. IDEA之Translation翻译插件-TKK: 更新 TKK 失败
  12. 十年总结(15):产品化-有心杀敌,无力回天
  13. Docker 4.2:Docker 公有镜像仓库 - 阿里云容器镜像服务
  14. win10轻松自动“备份和恢复”只要5步
  15. 网狐荣耀斗地主等15合1(美女图)
  16. Windows开启FTP服务
  17. 《你拥有的最宝贵的财富是什么》作业
  18. 【存储知识】NAS存储
  19. JS sort函数(按照首字母字符排序)
  20. 【web学习之mysql】 mysql- 学习 - 城市选择

热门文章

  1. Mysql修改数据库名方法
  2. 苹果笔的代替笔有哪些?Ipad好用电容笔测评
  3. Python--递归初步
  4. 机器学习中常用的分类算法总结
  5. Hadoop修改slaves的主机名,所要修改的文件
  6. Spring @Scheduled 使用详解
  7. matlab应力分析,MATLAB有限元分析与应用概述.ppt
  8. E575: viminfo: Illegal starting char in line: ^I+^I14^I33
  9. js中exec()函数的使用
  10. vue项目 使用百度云 cyberplayer.js插件方法