Mysql系列-索引类型

news2025/7/24 2:38:25

一 、索引类型别

根据叶子节点的内容分类的索引类型

InnoDB 使用B+ tree 索引模型,根据叶子节点是否存储数(根据叶子节点的内容)分为主键索引和非主键索引;非主键索引包括:普通索引、唯一索引、组合索引主键索引的叶子节点存的是整行数据。在 InnoDB 里,主键索引也被称为聚簇索引(clustered index)。非主键索引的叶子节点内容是主键的值。在 InnoDB 里,非主键索引也被称为二级索引(secondary index)。基于非主键索引的查询需要多扫描一棵索引树。因此,我们在应用中应该尽量使用主键查询,也称为回表查询。使用主键索引查询会一次性查询出数据。

1.普通索引

MySQL中最基本的索引类型,没有限制,允许重复,允许NULL

CREATE INDEX index_code ON tb_student(code);

2.唯一索引

唯一索引跟普通索引类似,唯一索引列的值必须唯一,允许有空值。
如果是组合索引,则列值的组合必须唯一。
创建唯一索引通常使用 UNIQUE 关键字,例如电话号码必须唯一,创建唯一索引

CREATE INDEX index_phone_number ON tb_student(phone_number);

3.主键索引

主键索引其实也是唯一索引的一种,但是不允许值重复或者值为NULL。必须使用PRIMARY KEY,在创建表结构的时候创建,不能单独用CREATE 的方式创建,主键一般都是自增ID

4.全文索引

全文索引主要用来查找文本中的关键字,只能在 CHAR、VARCHAR 或 TEXT 类型的列上创建。在 MySQL 中只有 MyISAM 存储引擎支持全文索引。
全文索引允许在索引列中插入重复值和NULL。
不过对于大容量的数据表,生成全文索引非常消耗时间和硬盘空间。
创建全文索引使用 FULLTEXT 关键字。

CREATE FULLTEXT INDEX index_name ON tb_student(name);

根据索引和数据存储方式分类存储方式

都属于B + tree的所有结构,那么他们的区别是什么呢?最大的区别就是存储方式的不同

聚簇索引

聚簇索引:将数据和索引放在一起存储,并且是按照顺序,数据的物理存放顺序和索引顺序是一直的,找到索引,就能找到数据

非聚簇索引

非聚簇索引:叶子节点不存数据,存储的是数据对应的地址,也就是说先要查询到地址,然后在去磁盘中找到对应的数据,因为数据和索引是分开的,举个例子,我们要找一本书中的某一个知识点,那么就需要先去目录中查询对应的章节页码,然后通过页码找到对应的那一页,这个目录就相当于索引,而那一页就是对应的数据

优点
聚簇索引查询可以直接获取数据,相比于非聚簇索引需要二次查询效率更高
聚簇索引的范围查询效率更高,因为是有序排列的
缺点
维护成本较高,特别是插入数据,会导致分页(page split),当数据插入一个已满的页中时,存储引擎就会把这一页分页,这样就导致占用更多磁盘空间
更新数据代价高,需要把更新后的行移动到新的位置

二 索引的规则

最左匹配原则

例如给日志表创建了3个联合索引,分别是
operate_type操作类型,
operate_user操作人,
operate_status操作状态

CREATE INDEX index_type_user_status ON eom_log(operate_type,operate_user,operate_status);

下面我们就来例如explain来看看是否命中索引

explain select * from eom_log where operate_type < 10

先来查一个字段,operate_type,结果如下,命中索引
在这里插入图片描述
再加一个字段,执行的结果也是命中索引

explain select * from eom_log where operate_type < 10 and operate_user < 10

在这里插入图片描述
那么如果我们查最右边的那个字段,会发生什么呢?很遗憾,没有走索引,
在这里插入图片描述
同意的道理,只查询中间字段,也是不走索引的

explain select * from eom_log where operate_user < 10

在这里插入图片描述
所以在多个字段组成的联合索引中,where条件中必须要从最左边的第一个字段开始匹配,如果没有就无法命中索引

那么问题又来了,如果只用第一个和第三个 字段当条件能命中索引吗?我们来试试

explain select * from eom_log where operate_type < 10 and operate_status  < 10

在这里插入图片描述
结果显示命中索引,所以只要where条件中包含最左边的字段,那么一定是命中

那么问题又来了,如果把这3个字段的顺序颠倒一下,能命中索引吗?

explain select * from eom_log where operate_user < 10 and operate_status  < 10 and operate_type < 10

在这里插入图片描述
结果显示命中索引,这里可能会有小伙伴问,不是最左匹配吗,其实这是mysql的优化器的功劳,优化器会判断纠正这条sql语句该以什么样的顺序执行效率最高,他会排列where的查询顺序,使他能够命中索引,最后才生成真正的执行计划。所以mysql查询优化器会最终以这种顺序进行查询执行。

覆盖索引

覆盖索引就是SQL只需要通过索引就可以返回查询所需要的数据,而不必通过二级索引查到主键之后再去查询数据。说白了,就是你的查询走到了索引,并且需要返回的数据刚好是索引的组成字段,不需要回表就能得到想要的结果;
简单粗暴理解:如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫做覆盖索引,如根据主键查询走主键索引,或者如下情况

看看例子,有个学生表student,里面有个联合索引学号和电话号码index_code_phone

SELECT code,phone from tb_user where code = 'a' and phone = 'b'

那么这个要查询的code 和phone 正好索引,那么查询的时候就直接能够返回数据,不需要走二次查询,这就是覆盖索引
覆盖索引的优点

  • 减少了磁盘I/O,提高了查询速度

  • 减少了内存占用,节省了资源

  • 减少了锁的竞争,提高了并发能力,它可以避免回表查询原始数据,从而减少了对数据行的访问和锁定。如果使用索引覆盖,那么只需要对索引记录加锁,而不需要对数据记录加锁。这样就可以减少锁的范围和冲突,提高并发能力

覆盖索引的缺点

  • 增加了索引的大小,占用了更多的磁盘空间
  • 增加了数据更新的开销,因为每次更新数据都需要更新索引
    因此,在创建覆盖索引时,我们需要权衡利弊,选择合适的字段和顺序,避免创建过多或过大的索引。

索引下推

索引下推(Index Condition Pushdown,简称ICP),是MySQL5.6版本的新特性,它能减少回表查询次数,提高查询效率。索引下推是指在使用联合索引时,将过滤条件下推到索引层,从而减少回表的次数。索引下推的下推其实就是指将部分上层(服务层)负责的事情,交给了下层(引擎层)去处理。索引下推的目的是为了减少回表次数,也就是要减少IO操作。对于的聚簇索引来说,数据和索引是在一起的,不存在回表这一说。

索引下推原理

我们来具体看一下,在没有使用ICP的情况下,MySQL的查询:
存储引擎读取索引记录;
根据索引中的主键值,定位并读取完整的行记录;
存储引擎把记录交给Server层去检测该记录是否满足WHERE条件。

使用ICP的情况下,查询过程
存储引擎读取索引记录(不是完整的行记录);
判断条件部分能否用索引中的列来做检查,条件不满足,则处理下一行索引记录;
条件满足,使用索引中的主键去定位并读取完整的行记录(就是所谓的回表);
存储引擎把记录交给层,层检测该记录是否满足条件的其余部分。

例如,假设我们有一个订单表,包含了订单的id,用户id,商品id,价格等字段,我们想要查询所有用户id为1且价格大于1000的订单的商品id和价格,那么我们可以创建一个包含了用户id,价格和商品id的联合索引,这样在扫描索引时就可以先过滤掉不满足用户id为1或价格大于1000的记录,而不需要回表查询订单表。

与联合索引不同的是,联合索引只能在查询条件中包含索引的前缀部分时才能生效,而索引下推可以在查询条件中包含任意部分的索引时生效。 例如,如果一个联合索引是(a,b,c),那么只有当查询条件中包含a或者a和b时才能使用该索引,而如果查询条件中只包含b或者c时则不能使用该索引。 但是如果使用了索引下推,那么即使查询条件中只包含b或者c,也可以将这些条件下推到索引层面上进行过滤,从而减少回表的次数和范

索引下推的具体实践

理论比较抽象,我们来上一个实践。使用一张用户表tuser,表里创建联合索引(name, age)
在这里插入图片描述
如果现在有一个需求:检索出表中名字第一个字是张,而且年龄是10岁的所有用户。那么,SQL语句是这么写的:

select * from tuser where name like '张%' and age=10;

假如你了解索引最左匹配原则,那么就知道这个语句在搜索索引树的时候,只能用 张,找到的第一个满足条件的记录id为1
在这里插入图片描述
那接下来的步骤是什么呢?
没有使用ICP
在MySQL 5.6之前,存储引擎根据通过联合索引找到name likelike ‘张%’ 的主键id(1、4),逐一进行回表扫描,去聚簇索引找到完整的行记录,server层再对数据根据age=10进行筛选。

我们看一下示意图:
在这里插入图片描述
可以看到需要回表两次,把我们联合索引的另一个字段age浪费了。
使用ICP
而MySQL 5.6 以后, 存储引擎根据(name,age)联合索引,找到,由于联合索引中包含列,所以存储引擎直接再联合索引里按照age=10过滤。按照过滤后的数据再一一进行回表扫描。

我们看一下示意图:
在这里插入图片描述
可以看到只回表了一次。

除此之外我们还可以看一下执行计划,看到Extra一列里 Using index condition,这就是用到了索引下推。

在这里插入图片描述

索引下推使用条件

只能用于range、 ref、 eq_ref、ref_or_null访问方法;

只能用于InnoDB和 MyISAM存储引擎及其分区表;

对存储引擎来说,索引下推只适用于二级索引(也叫辅助索引);

索引下推的目的是为了减少回表次数,也就是要减少IO操作。对于的聚簇索引来说,数据和索引是在一起的,不存在回表这一说。

引用了子查询的条件不能下推;

引用了存储函数的条件不能下推,因为存储引擎无法调用存储函数。

索引下推优缺点

索引下推的优点

  • 减少了回表的次数和范围,提高了查询速度
  • 减少了数据传输量和网络开销
    索引下推的缺点
  • 增加了索引扫描的复杂度和开销
  • 可能会导致误判或漏判,因为索引层无法处理一些复杂或模糊的过滤条件

因此,在使用索引下推时,我们需要注意一些限制和条件,比如:

  • 索引下推只适用于联合索引
  • 索引下推只适用于部分数据类型和操作符
  • 索引下推可能会受到优化器的影响

相关系统参数

索引条件下推默认是开启的,可以使用系统参数optimizer_switch来控制器是否开启。
查看默认状态:

mysql> select @@optimizer_switch\G;
*************************** 1\. row
: index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on
1 row in set (0.00 sec)

切换状态:

set ="index_condition_pushdown=off";
set ="index_condition_pushdown=on";

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

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

相关文章

sql-50练习题16-20

sql-50练习题16-20 前言数据库表结构介绍学生表课程表成绩表教师表 1-6 检索"01"课程分数小于60&#xff0c;按分数降序排列的学生信息1-7 按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩1-8 查询各科成绩最高分、最低分和平均分&#xff1a;以如下形式…

上海亚商投顾:三大指数小幅调整,医药股继续活跃

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 市场情绪 沪指昨日弱势震荡&#xff0c;尾盘探底回升一度翻红&#xff0c;深成指盘中跌超1%&#xff0c;午后跌幅有所收窄。…

最优值函数二

一、扫地机器人的示例 我们可以明确给出扫地机器人的Bellman最优方程。为了使问题更简洁&#xff0c;我们将状态高和低以及动作搜索、等待和充电分别缩写为h、l、s、w和re。由于只有两个状态&#xff0c;Bellman最优方程由两个方程组成。v∗(h)的方程可以写成&#xff1a; 按照…

飞鼠异地组网工具全网互通实战指南

飞鼠异地组网工具全网互通实战指南 一、飞鼠异地组网工具介绍1.1 飞鼠工具简介1.2 飞鼠工具官网 二、本次实践介绍2.1 本次实践前提2.2 本次实践简介2.3 本次实践环境规划 三、异地组网配置3.1 进入中心控制器节点管理后台3.2 网卡设置3.3 进入子网节点管理后台3.4 网卡设置 四…

EasyExcel动态复杂表头导出设置方法

目录 需求分析解决方案数据问题 需求分析 公司数据比较特殊有一部分数据需要动态修改导致信息导入时表头是不确定的&#xff0c;但其中又有一部分表头是固定的&#xff0c;如下图所示&#xff0c;如果表头全部是固定的话可以通过EasyExcel实体类的注解很轻松的解决&#xff0c…

解决CSS中height:100%失效的问题

出现BUG的场景&#xff0c;点击退出到登录页面&#xff0c;发现高度不对 上面出现了一种只是占了内容的高度&#xff0c;没有占满100%&#xff0c;为什么会出现这种情况呐&#xff1f; 让div的height"100%"&#xff0c;执行网页时&#xff0c;css先执行到&#xff0…

力扣刷题 day61:10-31

1.单词规律 给定一种规律 pattern 和一个字符串 s &#xff0c;判断 s 是否遵循相同的规律。 这里的 遵循 指完全匹配&#xff0c;例如&#xff0c; pattern 里的每个字母和字符串 s 中的每个非空单词之间存在着双向连接的对应规律。 方法一&#xff1a;双哈希表 #方法一&…

“碳”索未来,“汇”聚双碳

10月28日在广东省惠州市由汇林盛源低碳科技&#xff08;广东&#xff09;有限公司开办的2023汇林绿碳经济发展专题交流会取得圆满成功。 本次交流会基于我国在2030年达到碳达峰&#xff0c;2060年达到碳中和的目标&#xff0c;提出了汇林盛源公司在绿碳经济领域特有的优势与思考…

jeecg-uniapp 杂七杂八数据

uniapp 点击事件 tap: 单击事件 confirm: 回车事件 blur:失去焦点事件 touchstart: 触摸开始事件 touchmove: 触摸移动事件。 touchend: 触摸结束事件。 longpress: 长按事件。 input: 输入框内容变化事件。 change: 表单元素值变化事件。 submit: 表单提交事件。 scroll: 滚动…

Servlet的继承树,生命周期和线程不安全

1、Servlet 继承树 3)Servlet的继承树 - Servlet接口public interface Servlet{public void init(config);public void service(request,response);public void destroy();} - GenericServlet抽象类public abstract class GenericServlet implements Servlet{实现了init方法和d…

LiveMedia视频管理平台如何接入海康大华前端设备

LiveMedia视频管理平台支持对局域网内海康、大华、ONVIF设备及已经注册的GB28181前端&#xff0c;进行自动搜索&#xff0c;添加&#xff0c;简化添加流程。 接入海康大华设备示例 登陆视频中间件进入平台配置页面 点击上图设备管理&#xff0c;进入设备管理界面 点击设备发现…

J2EE项目部署与发布(Linux版本)

目录 一.jdk&tomcat安装 1.jdk的安装 1.2解压对应的安装包 1.3配置环境变量 2.tomcat的安装 二.mysql的安装 三.后端接口部署 后端部署 导入war包 修改端口 开启访问 一.jdk&tomcat安装 1.jdk的安装 登录VMware Workstation Pro 然后连接MobaXterm 将 jd…

ctfhub技能树web题目全解

Rce 文件包含 靶场环境 重点是这个代码&#xff0c;strpos&#xff0c;格式是这样的strpoc&#xff08;1&#xff0c;2&#xff0c;3&#xff09; 1是要搜索的字符串&#xff0c;必须有&#xff1b;2是要查询的字符串&#xff0c;必须有&#xff1b;3是在何处开始查询&#…

精明玩家的防骗攻略!绝地求生作图工具推荐!

亲爱的游戏玩家们&#xff0c;大家好&#xff01;在这个充满欢乐的游戏世界中&#xff0c;我们总是不可避免地会面临一些骗局和风险。为了保护自己的权益和游戏账号的安全&#xff0c;我们需要一些实用的方法和工具来帮助我们游戏更放心。 首先&#xff0c;防止被骗游戏账号黑名…

SpringBoot的核心配置:YAML概述、基础语法;JSR303数据校验;多环境切换

SpringBoot核心配置 SpringBoot配置文件分类 SpringBoot是基于约定的&#xff0c;所以很多配置都有默认值&#xff0c;但如果想使用自己的配置替换默认配置的话&#xff0c;就可以使用 application.properties或者application.yml&#xff08;application.yaml&#xff09;进…

“VVIC API:一键获取海量商品列表,根据关键词精准匹配,助力商家抢占市场先机!“

VVIC API接口可以根据关键词获取商品列表。以下是使用VVIC API接口获取商品列表的步骤&#xff1a; 确认VVIC API接口的请求地址和所需参数。根据接口文档中的说明设置请求参数&#xff0c;包括关键词和其他筛选条件。发送HTTP GET请求到API地址&#xff0c;即可得到对应的调用…

错误: 找不到或无法加载主类 回归java运行的本质

错误: 找不到或无法加载主类 回归java运行的本质 一&#xff0c;背景 当有了idea这种工具后&#xff0c;java的mian方法执行起来是如此简单&#xff0c;很少有人再手动编辑并通过命令行执行了。 同时&#xff0c;在当今Spring Boot盛行的今天&#xff0c;恐怕很少再有人执行j…

cmake多目录构建初步成功

目录和代码和 首次cmake 多目录构建失败 此文一样&#xff1b; 只有一个CMakeLists.txt&#xff1b; cmake_minimum_required(VERSION 3.10) project(mytest3 VERSION 1.0) include_directories("${PROJECT_SOURCE_DIR}/include") add_executable(mytest3 src/main…

二叉树问题——前/中/后/层遍历问题(递归与栈)

摘要 博文主要介绍二叉树的前/中/后/层遍历(递归与栈)方法 一、前/中/后/层遍历问题 144. 二叉树的前序遍历 145. 二叉树的后序遍历 94. 二叉树的中序遍历 102. 二叉树的层序遍历 103. 二叉树的锯齿形层序遍历 二、二叉树遍历递归解析 // 前序遍历递归LC144_二叉树的前…

[PHP]DBErp进销存系统 v1.1 RC 221101

DBErp系统&#xff0c;是北京珑大钜商科技有限公司 基于 Laminas doctrine 2 开发的一套进销存系统。 本系统运行环境要求&#xff1a; 服务器系统&#xff1a;Linux&#xff08;推荐&#xff09;、Unix、Windows Web服务软件&#xff1a;Apache&#xff08;推荐&#xff09;…