聚集索引、辅助索引、覆盖索引、联合索引

转载自   聚集索引、辅助索引、覆盖索引、联合索引

聚集索引(Clustered Index)

聚集索引就是按照每张表的主键构造一棵B+树,同时叶子节点中存放的即为整张表的行记录数据。

举个例子,直观感受下聚集索引。

创建表t,并以人为的方式让每个页只能存放两个行记录(不清楚怎么人为控制每页只存放两个行记录):

 

最后《MySQL技术内幕》的作者通过分析工具得到这棵聚集索引树的大致构造如下: 

聚集索引的叶子节点称为数据页,每个数据页通过一个双向链表来进行链接,而且数据页按照主键的顺序进行排列。

如图所示,每个数据页上存放的是完整的行记录,而在非数据页的索引页中,存放的仅仅是键值及指向数据页的偏移量,而不是一个完整的行记录。

如果定义了主键,InnoDB会自动使用主键来创建聚集索引。如果没有定义主键,InnoDB会选择一个唯一的非空索引代替主键。如果没有唯一的非空索引,InnoDB会隐式定义一个主键来作为聚集索引。


辅助索引(Secondary Index)

辅助索引,也叫非聚集索引。和聚集索引相比,叶子节点中并不包含行记录的全部数据。叶子节点除了包含键值以外,每个叶子节点的索引行还包含了一个书签(bookmark),该书签用来告诉InnoDB哪里可以找到与索引相对应的行数据。

还是以《MySQL技术内幕》中的例子,来直观感受下辅助索引的模样。

还是以上面的表t为例,在列c上创建非聚集索引:

 

然后作者通过分析工作得到辅助索引和聚集索引的关系图:

 

可以看到辅助索引idx_c的叶子节点中包含了列c的值和主键的值。

以Key为7fffffff为例,7是0111,0代表负数,真实的值应该取反加1,是-1,这是列c的值。Pointer是80000001,8是1000,1代表正数,所以80000001代表1,是主键的值。


覆盖索引(Covering index)

InnoDB存储引擎支持覆盖索引,即从辅助索引中就可以得到查询的记录,而不需要查询聚集索引中的记录。

使用覆盖索引有啥好处?

  • 可以减少大量的IO操作

上图中我们知道,如果要查询辅助索引中不含有的字段,得先遍历辅助索引,再遍历聚集索引,而如果要查询的字段值在辅助索引上就有,就不用再查聚集索引了,这显然会减少IO操作。

比如上图中,以下sql可以直接使用辅助索引,

select a from where c = -2;
  • 有助于统计

    假设存在如下表:

  CREATE TABLE `student` (`id` bigint(20) NOT NULL,`name` varchar(255) NOT NULL,`age` varchar(255) NOT NULL,`school` varchar(255) NOT NULL,PRIMARY KEY (`id`),KEY `idx_name` (`name`),KEY `idx_school_age` (`school`,`age`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

如果在该表上执行:

select count(*) from student

优化器会怎么处理?

遍历聚集索引和辅助索引都可以统计出结果,但辅助索引要远小于聚集索引,所以优化器会选择辅助索引来统计。执行explain命令:

 

key和Extra显示使用了idx_name这个辅助索引。

还有,假设执行以下sql:

select *  from student where age > 10 and age < 15

因为联合索引idx_school_age的字段顺序是先school再age,按照age做条件查询,通常不走索引: 

但是,如果保持条件不变,查询所有字段改为查询条目数:

select count(*) from student where age > 10 and age < 15

优化器会选择这个联合索引: 


联合索引

联合索引是指对表上的多个列进行索引。

以下为创建联合索引idx_a_b的示例:

 

联合索引的内部结构:

联合索引也是一棵B+树,其键值数量大于等于2。键值都是排序的,通过叶子节点可以逻辑上顺序的读出所有数据。数据(1,1)(1,2)(2,1)(2,4)(3,1)(3,2)是按照(a,b)先比较a再比较b的顺序排列。

基于上面的结构,对于以下查询显然是可以使用(a,b)这个联合索引的:

select * from table where a=xxx and b=xxx ;select * from table where a=xxx;

但是对于下面的sql是不能使用这个联合索引的,因为叶子节点的b值,1,2,1,4,1,2显然不是排序的。

select * from table where b=xxx

联合索引的第二个好处是对第二个键值已经做了排序。举个例子:

create table buy_log(userid int not null,buy_date DATE
)ENGINE=InnoDB;insert into buy_log values(1, '2009-01-01');
insert into buy_log values(2, '2009-02-01');alter table buy_log add key(userid);
alter table buy_log add key(userid, buy_date);

当执行

select * from buy_log where user_id = 2;

时,优化器会选择key(userid);但是当执行以下sql:

select * from buy_log where user_id = 2 order by buy_date desc;

时,优化器会选择key(userid, buy_date),因为buy_date是在userid排序的基础上做的排序。

如果把key(userid,buy_date)删除掉,再执行:

select * from buy_log where user_id = 2 order by buy_date desc;

优化器会选择key(userid),但是对查询出来的结果会进行一次filesort,即按照buy_date重新排下序。所以联合索引的好处在于可以避免filesort排序。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/326497.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2019蓝桥杯省赛---java---B---6(特别数的和)

题目描述 时间限制: 1.0s 内存限制: 512.0MB 本题总分&#xff1a;15 分【问题描述】小明对数位中含有 2、0、1、9 的数字很感兴趣&#xff08;不包括前导 0&#xff09;&#xff0c;在 1 到 40 中这样的数包括 1、2、9、10 至 32、39 和 40&#xff0c;共 28 个&#xff0c;他…

.NET Core项目部署到linux(Centos7)

1.开篇说明 a 上篇博客简单的说明了一下 使用.NET Core开发的一个总结&#xff08;.NET Core跨平台&#xff1a;使用.NET Core开发一个初心源商城总括)&#xff0c;那么这篇博客我们就在上一篇博客的基础上对其代码进行部署&#xff0c;将其部署在Linux Centos7下。 b 这周周二…

2020蓝桥杯省赛---java---B---1(指数计算)

题目描述 代码实现 解法一 计算器 解法二 package com.atguigu.lanqiao;import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner input new Scanner(System.in);int a1,b1921,c7;for (int i 0; i < 2020; i) {aa*7;if(a>1…

ASP.NET Core 优雅的在开发环境保存机密(User Secrets)

前言 在应用程序开发的过程中&#xff0c;有的时候需要在代码中保存一些机密的信息&#xff0c;比如加密密钥&#xff0c;字符串&#xff0c;或者是用户名密码等。通常的做法是保存到一个配置文件中&#xff0c;在以前我们会把他保存到web.config中&#xff0c;但是在ASP.NET C…

震惊,中国历朝历代疆域变迁视频【高清】

中国历代疆域指的是从古至今中国领土变化过程的历史&#xff0c;期间经过数千年的发展历程。 中国疆域自远古以来不断演进变化&#xff0c;从《尚书禹贡》九州开始直到唐朝极盛时疆域:被认为是中国疆域原型。至元朝时不仅统一中国&#xff0c;西藏地方从此正式纳入中国中央政府…

2020蓝桥杯省赛---java---B---2(指数计算)

题目描述 【问题描述】 小明设计了一种文章加密的方法&#xff1a;对于每个字母 c&#xff0c;将它变成某个另外的字符 Tc。下表给出了字符变换的规则&#xff1a; 例如&#xff0c;将字符串 YeRi 加密可得字符串 EaFn。 小明有一个随机的字符串&#xff0c;加密后为 EaF…

java项目新东方在线源码_[VIP源码]【S019】SSM框架开发智夫子在线考试系统项目源码 百度云盘...

java源码项目名称&#xff1a;SSM框架开发智夫子在线考试系统项目源码ssm项目源码5 y& C [0 w! J% F1 n8 z J百度网盘下载链接&#xff1a;4 B i* }. G4 }8 |7 l% G8 游客&#xff0c;如果您要查看本帖隐藏内容请->>回复[/hide]_* r Q0 _! W1 K4 Q" U6 F密码: …

关于Dapper.NET的相关论述

年少时&#xff0c;为何不为自己的梦想去拼搏一次呢&#xff1f;纵使头破血流&#xff0c;也不悔有那年少轻狂。感慨很多&#xff0c;最近事情也很多&#xff0c;博客也很少更新了&#xff0c;毕竟每个人都需要为自己的生活去努力。 最近在一个群里遇到一个人说的话&#xff0c…

数年之前的寒假

版权声明&#xff1a;文章可以随便转载&#xff0c;但是转载时带上原文地址来源&#xff0c;侵权必究 https://blog.csdn.net/qq_34137397/article/details/54882702对于上学的孩子来说每年都有寒假&#xff0c;可是一样的寒假总是不一样的玩法。自从高中毕业之后&#xff0c;很…

js object 常用方法总结

转载自 js object 常用方法总结 Object.assign(target,source1,source2,...) 该方法主要用于对象的合并&#xff0c;将源对象source的所有可枚举属性合并到目标对象target上,此方法只拷贝源对象的自身属性&#xff0c;不拷贝继承的属性。 Object.assign方法实行的是浅拷贝&…

发布 ASP.NET Core 应用

第一步&#xff1a;运行 dotnet restore 命令&#xff0c;以还原项目中指定的依赖项 1 dotnet restore 第二步&#xff1a;使用 dotnet build 命令为目标平台上的应用创建调试版本。 如果不指定想要生成的运行时标识符&#xff0c;则 dotnet build 命令将会创建仅适用于当前系统…

继承类对方法的影响java_4-Java面向对象-继承(上)

什么是继承?继承有哪些特点?我们在Java中如何实现继承?程序中的继承(面向对象编程思想来源于生活):解决重复代码的出现问题。抽取共性生成父类。此时猫和狗直接继承父类将可以直接使用父类的这些成员属性和方法。此时子类当中的方法就可以只写子类所特有的东西。特点: 1. 利…

javaSE基础代码案例

package org.test; import java.util.Arrays; import java.util.Scanner;/*** * 项目名称&#xff1a;Test * 类名称&#xff1a;TestMain * 类描述&#xff1a; * 创建人&#xff1a;Mu Xiongxiong * 创建时间&#xff1a;2018-3-29 下午3:49:00 * 修改人&…

迪杰斯特拉算法(最短路径)

描述 算法过程 代码实现 package com.atguigu.dijkstra;import com.sun.xml.internal.fastinfoset.algorithm.BooleanEncodingAlgorithm;import javax.sound.midi.Soundbank; import java.util.Arrays; import java.util.TimerTask;public class DijkstraAlgorithm {public st…

MySQL instr()函数

转载自 MySQL instr()函数 MySQL INSTR函数简介 有时&#xff0c;您想要在字符串中查找子字符串或检查字符串中是否存在子字符串。在这种情况下&#xff0c;您可以使用字符串内置INSTR()函数。 INSTR()函数返回字符串中子字符串第一次出现的位置。如果在str中找不到子字符串…

如何给视频中插入视频,字幕,以及去掉前后广告

昨天白天接到了一个这样的需求&#xff0c;就是剪辑一段视频&#xff0c;给视频中加入插入一个剪短的介绍&#xff0c;然后把没有用的截取掉。 看起来很简单&#xff0c;确实&#xff0c;利用常用的视频剪辑软件就可以直接实现&#xff0c;但是事实并不是这样的&#xff0c;接…

ZKEACMS for .Net Core 深度解析

ZKEACMS 简介 ZKEACMS.Core 是基于 .Net Core MVC 开发的开源CMS。ZKEACMS可以让用户自由规划页面布局&#xff0c;使用可视化编辑设计“所见即所得”&#xff0c;直接在页面上进行拖放添加内容。 ZKEACMS使用插件式设计&#xff0c;模块分离&#xff0c;通过横向扩展来丰富CMS…

java design按钮_DesignJava 设计模式,讲述 的各种 方便在项目中进行 框架结构 Develop 238万源代码下载- www.pudn.com...

文件名称: DesignJava下载收藏√ [5 4 3 2 1 ]开发工具: Java文件大小: 1675 KB上传时间: 2013-11-21下载次数: 2提 供 者: 102426详细说明&#xff1a;JAVA设计模式&#xff0c;讲述java的各种设计模式&#xff0c;方便在项目中进行设计框架结构-JAVA design patterns, j…

剪辑视频、去掉爱剪辑前后广告、视频中添加黑幕简要教程

昨天白天接到了一个这样的需求&#xff0c;就是剪辑一段视频&#xff0c;给视频中加入插入一个剪短的介绍&#xff0c;然后把没有用的截取掉。看起来很简单&#xff0c;确实&#xff0c;利用常用的视频剪辑软件就可以直接实现&#xff0c;但是事实并不是这样的&#xff0c;接下…

弗洛伊德算法

思路分析 代码实现 package com.atguigu.floyd;import java.util.Arrays;public class FloydAlgorithm {public static void main(String[] args) {//测试看看图是否创建成功char[] vertex{A,B,C,D,E,F,G};//创建邻接矩阵int[][] matrixnew int[vertex.length][vertex.length]…