MySQL ② —— 索引原理

news2024/11/15 12:21:55

1. 索引

1.1 分类

  • 主键索引、唯一索引、普通索引、组合索引、以及全文索引

主键索引

  • 非空唯一索引,一个表只有一个主键索引;
  • 在 innodb 中,主键索引的 B+ 树包含表数据信息。

唯一索引

  • 不可以出现相同的值,可以有 NULL 值。

普通索引

  • 允许出现相同的索引内容。

组合索引

  • 对表上的多个列进行索引

全文索引

  • 将存储在数据库当中的整本书和整篇文章中的任意内容信息查找出来的技术;
  • 关键词 FULLTEXT。

1.2 主键选择

  • innodb 中表是索引组织表,每张表有且仅有一个主键;
  • 如果显示设置 PRIMARY KEY,则该设置的 key 为该表的主键;
  • 如果没有显示设置,则从非空唯一索引中选择;
    • 只有一个非空唯一索引,则选择该索引为主键;
    • 有多个非空唯一索引,则选择声明的第一个为主键;
  • 没有非空唯一索引,则自动生成一个 6 字节的 _rowid 作为主键。

1.3 约束

  • 为了实现数据的完整性,对于 innodb,提供了以下几种约束:primary key,unique key,foreign key,default,not null;
  • 外键约束:
    • 外键用来关联两个表,来保证参照完整性;MyISAM 存储引擎本身并不支持外键,只起到注释作用;而 innodb 完整支持外键, 并具备事务性;
  • 约束与索引的区别:
    • 创建主键索引或者唯一索引的时候同时创建了相应的约束;但是约束是逻辑上的概念;索引是一个数据结构既包含逻辑的概念也包含物理的存储方式;

2. 索引实现

2.1 索引存储

  • innodb 由段、区、页组成:
    • 段分为数据段、索引段、回滚段等;
    • 区大小为 1 MB(一个区由 64 个连续页构成);
    • 页的默认值为 16k;页为逻辑页,磁盘物理页大小一般为 4K 或者 8K;为了保证区中的页的连续,存储引擎一般一次从磁盘中申请4~5个区;
      • 页是 innodb 磁盘管理的最小单位;默认16K,可通过 innodb_page_size 参数来修改;
      • B+ 树的一个节点的大小就是该页的值。
        在这里插入图片描述

2.2 B+树

  • 全称:多路平衡搜索树;
  • 用来组织磁盘数据,以页为单位,物理磁盘页一般为 4K,innodb 默认页大小为 16K;
  • 对页的访问是一次磁盘 IO,缓存中会缓存常访问的页;
  • 特征:非叶子节点只存储索引信息,叶子节点存储具体数据信息;叶子节点之间互相连接,方便范围查询;
  • 每个索引对应着一个 B+ 树;
  • B+ 树的一个节点对应一个数据页;B+ 树的层越高,那么要读取到内存的数据页越多,IO 次数越多。
    在这里插入图片描述

2.3 聚集索引

  • 按照主键构造的 B+ 树;叶子节点中存放数据页;数据也是索引的一部分;
  • 一个索引代表着一个B+树,修改非主键索引就会修改自己的和聚集索引两个B+树,修改一个元素只需要修改聚集索引的B+树

例子1

slelect * from user where id >= 18 and id < 40;

在这里插入图片描述

2.4 辅助索引

  • 叶子节点不包含行记录的全部数据;辅助索引的叶子节点中, 除了用来排序的 key 还包含一个 bookmark ,用来存储聚集索引的 key。

例子 2

select * from user where lockyNum = 33;

在这里插入图片描述

3. innoDB体系结构

  • io速度:顺序内存io(数组)>> 随机内存io(红黑树)≈ 顺序磁盘io >> 随机磁盘io

在这里插入图片描述

  • buffer pool:缓存表和索引数据;采用 LRU 算法(如下图)让 Buffer pool 只缓存比较热的数据。
    在这里插入图片描述
  • change buffer:缓存辅助(二级)索引的数据变更(DML 操作),change buffer 中的数据将会异步 merge 到 buffer pool 中。
  • free list 组织 buffer pool 中未使用的缓存页;flush list 组织 buffer pool 中的脏页,也就是待刷盘的页;lru list 组织 buffer pool 中冷热数据,当 buffer pool 没有空闲页,将从 lru list 中最久未使用的数据进行淘汰。

在这里插入图片描述

4. 最左匹配原则

  • 对于组合索引,从左到右依次匹配,遇到 > < between like 就停止匹配;
  • 对于这样一个组合索引 key `name_cid_idx` ( `name`, `cid` )
    • 会先匹配name,都一样再匹配cid,不会直接就匹配cid
    • 如果查询语句没有name只有cid只会进行全表扫描而不是走辅助索引扫描

5. 覆盖索引

  • 从辅助索引中就能找到数据,而不需通过聚集索引查找;利用 辅助索引树高度一般低于聚集索引树;较少磁盘 IO。

6. 索引下推(面试经常问到)

  • 为了减少回表次数,提升查询效率;在 MySQL 5.6 的版本开始推出;
  • MySQL 架构分为 server 层和存储引擎层;
  • 没有索引下推机制之前,server 层向存储引擎层请求数据,在 server 层根据索引条件判断进行数据过滤;
  • 有索引下推机制之后,将部分索引条件判断下推到存储引擎中过滤数据;最终由存储引擎将数据汇总返回给 server 层。

7. 索引失效

  • select ... where A and B 若 A 和 B 中有一个不包含索引, 则索引失效;
  • 索引字段参与运算,则索引失效;例如:from_unixtime(idx) = ‘2021-04-30’;
  • 索引字段发生隐式转换,则索引失效;例如:将列隐式转换为某个类型,实际等价于在索引列上作用了隐式转换函数;
  • LIKE 模糊查询,通配符 % 开头,则索引失效;例如:select * from user where name like '%Mark';
  • 在索引字段上使用 NOT <> != 索引失效;如果判断 id <> 0 则修改为idx > 0 or idx < 0;
  • 组合索引中,没使用第一列索引,索引失效。

8. 索引原则

  • 查询频次较高且数据量大的表建立索引;索引选择使用频次较高,过滤效果好的列或者组合;
  • 使用短索引;节点包含的信息多,较少磁盘 IO 操作;比如: smallint,tinyint;
  • 对于很长的动态字符串,考虑使用前缀索引;
  • 对于组合索引,考虑最左侧匹配原则和覆盖索引;
  • 尽量选择区分度高的列作为索引;该列的值相同的越少越好;
  • 尽量扩展索引,在现有索引的基础上,添加复合索引;最多 6 个索引
  • 不要 select *; 尽量只列出需要的列字段;方便使用覆盖索引;
  • 索引列,列尽量设置为非空;
  • 可选:开启自适应 hash 索引或者调整 change buffer;
  • mysql遇到字符串和数字比较时,会自动将字符串转换为数字

9. 优化器成本分析

  • MySQL 优化器主要针对 IO 和 CPU 会计算语句的成本;可能不会按照分析的原理来执行语句;
  • 步骤:
    • 找出所有可能需要使用到的索引;
    • 计算全表扫描的代价;
    • 计算不同索引执行查询的代价;
    • 对比找出代价最小的执行方案;

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

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

相关文章

3.28学习总结

java 封装 封装体现了java的面向对象的特点,用户不用知道程序是如何运行的,只用按照所给的格式输入参数,便可得到对应的结果. 一个完整的封装需要每个实例变量都用private来修饰并拥有相应的public getter和setter方法. 代码 public class girl {private int age;public st…

TABLE使用篇之奇门异术

table使用时候有时候会有下面界面 hover提示框&#xff0c;用element的el-popover可以显示该操作&#xff0c;但是会发现 取消操作的时候&#xff0c;el-popover不会自动消失&#xff0c;虽然失去焦点改框会自动消失&#xff0c;但是看起来对用户不是很友好 解决办法&#xff…

CDH集群hive初始化元数据库失败

oracle数据库操作&#xff1a; 报错如下&#xff1a;命令 (Validate Hive Metastore schema (237)) 已失败 截图如下&#xff1a; 后台日志部分摘录&#xff1a; WARNING: Use “yarn jar” to launch YARN applications. SLF4J: Class path contains multiple SLF4J binding…

Vite 为什么比 Webpack 快?

目录 1. Webpack 的构建原理 2. Script 的模块化&#xff08;主流浏览器对 ES Modules 的支持&#xff09; 3. Webpack vs Vite 开发模式的差异 对 ES Modules 的支持 底层语言的差异 热更新的处理 1. Webpack 的构建原理 前端之所以需要类似于 Webpack 这样的构建工具&…

vue纯前端过滤嵌套数据,通过关键字搜索过滤嵌套数据

1.过滤效果&#xff1a; 2. cardList 数据源&#xff1a; [ { "id": 4, "createTime": "2024-03-28 02:47:18", "updateTime": "2024-03-28 02:47:18", "uniqueId": "…

前端学习-CSS基础-Day3

一、CSS三大特性 1.1层叠性 相同选择器给设置相同的样式&#xff0c;此时一个样式就会覆盖&#xff08;层叠&#xff09;另一个冲突的样式。层叠性主要解决样式冲突的问题 层叠性原则&#xff1a; 1.样式冲突&#xff0c;遵循的原则是就近原则&#xff0c;哪个样式离结构近&a…

React系列之合成事件与事件处理机制

文章目录 React事件处理机制原生事件的事件机制事件代理&#xff08;事件委托&#xff09; 合成事件使用合成事件目的合成事件原生事件区别事件池 原生事件和React事件的执行顺序e.stopPropagation() React17事件机制的修改 React事件处理机制 react 事件机制基本理解&#xf…

Maven配置国内镜像-阿里云仓库镜像

使用自己安装maven环境时&#xff1a; 打开解压目录下conf/settings.xml文件 使用Idea自带的Maven时&#xff1a; 打开Idea安装路径\plugins\maven\lib\maven3\conf\settings.xml文件 在mirrors节点中加入如下配置&#xff1a; <!-- 加入如下mirror节点 使用国内阿里云仓…

fastadmin学习05-开启debug以及配置

FastAdmin 框架提供了对 .env 环境变量配置的支持&#xff0c;并附带一个默认示例文件 .env.sample。在安装后&#xff0c;框架并不会自动启用 env 环境变量&#xff0c;需要手动将 .env.sample 复制为 .env 并进行配置。 如果不开启.env会读取database.php中的配置 下面测试…

鸿蒙OS开发实例:【页面传值跳转】

介绍 本篇主要介绍如何在HarmonyOS中&#xff0c;在页面跳转之间如何传值 HarmonyOS 的页面指的是带有Entry装饰器的文件&#xff0c;其不能独自存在&#xff0c;必须依赖UIAbility这样的组件容器 如下是官方关于State模型开发模式下的应用包结构示意图&#xff0c;Page就是…

基于单片机智能温控风扇调速系统设计

**单片机设计介绍&#xff0c;基于单片机智能温控风扇调速系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机智能温控风扇调速系统设计概要主要涉及到硬件设计、温度检测、风扇控制以及可能的拓展功能等方面。以…

Machine Learning机器学习之贝叶斯网络(BayesianNetwork)

目录 前言 算法提出背景&#xff1a; 贝叶斯算法特点&#xff1a; 一、贝叶斯定理 二、朴素贝叶斯分类模型 1、朴素贝叶斯分类模型&#xff08;Naive Bayes Classifier&#xff09; 2、原理 2.1 朴素贝叶斯假设 2.2条件独立性假设 2.3后验概率计算 2.4类别预测 2.5小结 3、建模…

Postman测试含有变量的接口的方法

1.在路径中用/&#xff1a;设置变量名 2.设置token验证 3.填写参数

Vue 04 Vue 中的 Ajax、slot 插槽

Vue学习 Vue 0401 Vue中的Ajax服务器准备axios使用跨域问题解决Vue-CLI 配置代理1Vue-CLI 配置代理2案例: 用户搜索vue-resource 02 slot插槽默认插槽具名插槽作用域插槽slot总结 Vue 04 B站 Vue全家桶&#xff08;BV1Zy4y1K7SH&#xff09; 学习笔记 Vue 中的 ajax 01 Vue中的…

Unity 学习日记 12.小球撞击冰块游戏

目录 1.准备场景 2.让小球动起来 3.用鼠标把小球甩出去 4.加入鼠标点击小球的判断 5.小球与冰块的碰撞测试 6.撞击后销毁冰块 ​编辑 7.显示游戏计时 8.显示扔球次数 9.显示剩余冰块个数 10.游戏结束 11.完整代码 下载源码 UnityPackage 最终效果&#xff1a; 1.准…

Idea2023.3.6版本无法启动设置界面-settings界面打不开无反应---IntelliJ Idea工作笔记013

先说一下网上有,把某个文件删除的 有说是因为汉化问题的 可以看到,其实都不是,这样弄就好了,很简单 Please report thisjava.lang.ClassCastException: class [Lcom.intellij.execution.filters.CompositeInputFilter$InputFilterWrapper; cannot be cast to class java.uti…

关于使用vscode搭建c/c++编程环境

目录 关于使用vscode搭建c/c编程环境一、前言二、安装 IDE 二、安装TDM-GCC安装三、安装C/C环境四、编写代码并进行编译 关于使用vscode搭建c/c编程环境 一、前言 一直觉得vscode是生产强有力的生产工具&#xff0c;基于此&#xff0c;做一篇学习笔记进行记录。 二、安装 ID…

洛谷 P1379 八数码难题

代码如下&#xff1a; #include<bits/stdc.h> using namespace std; struct node{string s;int pos; }star,en; map<string,int>mp[2]; queue<node>q[2]; int main(){cin>>star.s;en.s"123804765";for(int i0;i<9;i){if(star.s[i]0) sta…

服务器停止解析域名,但仍然可以访问到

1.centos7 如何刷新dns缓存 在CentOS 7上&#xff0c;DNS缓存由nscd&#xff08;Name Service Cache Daemon&#xff09;管理&#xff0c;如果系统上安装了nscd&#xff0c;可以通过清除nscd缓存来刷新DNS缓存。 要刷新DNS缓存&#xff0c;请执行以下命令&#xff1a; sudo …

【XXL-JOB】执行器架构设计和源码解析

简介 XXL-JOB是一个分布式任务调度平台&#xff0c;其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线&#xff0c;开箱即用。 XXL-JOB分为B/S架构&#xff0c;调用中心是XXL-JOB服务端&#xff0c;执行器是客户端。 调度中心核…