当前位置: 首页 > article >正文

MySQL索引原理以及SQL优化(二)

目录

1. 索引与约束

1.1 索引是什么

1.2 索引的目的

1.3 索引分类

        1.3.1 数据结构

        1.3.2 物理存储

        1.3.3 列属性

        1.3.4 列的个数

1.4 主键的选择

1.5 索引使用场景

1.6 索引的底层实现

        1.6.1 索引存储

        1.6.2 页

        1.6.3 B+ 树

        1.6.4 B+ 树层高问题

        1.6.5 自增 id 

1.7 innodb 体系结构

        1.7.1 buffer pool

        1.7.2 change buffer

1.8 覆盖索引

1.9 最左匹配规则

1.10 索引下推

1.11 索引失效

1.12 索引原则

2. SQL 语句速度慢处理

2.1 找到 SQL 语句

2.2 分析SQL


1. 索引与约束

1.1 索引是什么
  • 索引是一种有序的数据结构,MySQL 中主要使用 B+ 树(InnoDB引擎)来组织索引
  • 加快数据检索速度来提升数据库的查询效率(例如 "目录" 或是 "页码")
  • 按照单个或者多个进行排序
1.2 索引的目的

        提升搜索效率

1.3 索引分类
        1.3.1 数据结构

                1. B+ 树索引

                所有数据存储在叶子节点,非叶子节点仅存储索引键和指针,支持范围查询和随机访问,适合磁盘存储结构。

                2.hash 索引

                使用哈希函数将键值映射到哈希表,支持 O (1) 的等值查询,存在哈希冲突问题,但不支持范围查询。

                3.全文索引

                采用倒排索引结构,支持文本内容的模糊匹配和语义查询。

        1.3.2 物理存储

                1. 聚集索引(聚簇索引)

                数据行的物理存储顺序与索引顺序完全一致,每个表只能有一个聚集索引。主键默认创建聚集索引。

                2.辅助索引(二级索引)

                索引节点存储主键值而非数据地址,查询时需要先查索引再查主键索引,产生回表操作。可存在多个二级索引。

        1.3.3 列属性

                1.主键索引

                特殊的唯一索引,不允许NULL值。InnoDB引擎中自动成为聚集索引,保证数据物理有序性。

                2.唯一索引

                强制列值的唯一性约束,允许NULL值(但只能有一个NULL)。

                3.普通索引

                无唯一性约束的基础索引类型,允许重复值和NULL值。查询优化器可根据代价模型选择使用。

                4.前缀索引

                对字符类型字段前N个字符建立索引,通过计算选择性 确定最优前缀长度。

        1.3.4 列的个数

                1.单列索引

                在单个字段上建立的索引,查询条件精确匹配该字段时效率最高。

                2.组合索引

                在多个字段上建立的联合索引,遵循最左匹配原则。

1.4 主键的选择

        innodb 中表是索引组织表,每张表有且仅有一个主键;

  1. 如果显示设置 PRIMARY KEY ,则该设置的 key 为该表的主键;
  2. 如果没有显示设置,则从非空唯一索引中选择;
  3. 只有一个非空唯一索引,则选择该索引为主键;
  4. 有多个非空唯一索引,则选择声明的第一个为主键;
  5. 没有非空唯一索引,则自动生成一个 6 字节的 _rowid 作为主键;
1.5 索引使用场景

        索引常常用在筛选条件的适合使用,例如

        where     |     group by   |  order by 

        在以下场景,不要使用

  •         没有 where/group by/ order by 的场景
  •         区分度不高的列
  •         经常修改的列
  •         表数据量少
1.6 索引的底层实现
        1.6.1 索引存储
  1. 索引存储的数据结构通常是 B+ 树,而不是哈希表
  2. 索引是磁盘上的有序结构,不是存在内存中的

        1.6.2 页
  1. innoDB 的数据存储以 页(Page) 为最小单位,每一页大小通常是 16KB。
  2. 一棵 B+ 树的每个节点对应一个或多个磁盘页
  3. 数据读写以页为单位进行(减少磁盘 I/O 次数)
        1.6.3 B+ 树
  1. B+树是数据库默认的索引结构
  2. 每个节点存放有序的数据键值+指向子节点的指针
  3. 所有数据都存放在叶子节点
  4. 叶子节点之间有链表连接(范围查询快)
        1.6.4 B+ 树层高问题
  1. 理想状态下,B+树的高度很低,一般在 2-4层
  2. 为什么?
    因为一页(16KB)能存很多索引项(假设一项占 16字节,1页能存1024项);所以即使存百万条数据,只要 2-3 次磁盘IO 就能找到,非常快!
        1.6.5 自增 id 
  1. 很多表喜欢用 自增ID(auto_increment) 作为主键。
  2. 自增ID的好处:
    插入数据总是追加到B+树的最右边;
    避免频繁分裂、重排;
    插入性能最好
    放心用,根本用不完

        相关问题

         1.为什么采用 " 多路 " 的树结构

        一个节点多条链路,相较于平衡二叉搜索树是一个更加矮胖的结构,树的高度越低,较少的磁盘io次数来检索数据

        2.为什么非叶子节点只存储索引信息

        B+ 树节点映射固定大小的磁盘数据,可以包含更多的索引信息,能快速锁定数据所在叶子节点位置

        3.为什么叶子节点依次相连

        便于范围查询,避免中序遍历回溯去查找下一个节点

总之:索引信息和数据信息的分层管理,便于高效的组织磁盘数据,快速实现单点和范围查询

1.7 innodb 体系结构
        1.7.1 buffer pool

Buffer Pool 是 InnoDB 把磁盘上的数据页、索引页、插入缓冲(Change Buffer)、自适应哈希索引等缓存到内存中的区域。
目的是:减少磁盘 I/O,提高数据库访问速度。

        特点:

  1. 查询数据时优先从 Buffer Pool 取(命中则速度很快)
  2. 如果没有命中,才从磁盘读入,并加入 Buffer Pool(可能引发淘汰机制,比如 LRU)
  3. 包括脏页管理(数据被修改但未刷盘)机制
        1.7.2 change buffer

 Change Buffer 是 InnoDB 中专门为二级索引的插入、更新、删除操作设置的缓存区域,延迟将二级索引变更写入磁盘,从而减少磁盘 I/O。

        free list 组织 buffer pool 中未使用的缓存页;flush list 组织 buffer pool 中脏页,也就是待刷盘的 页;lru list 组织 buffer pool 中冷热数据,当 buffer pool 没有空闲页,将从 lru list 中最久未使用的 数据进行淘汰。

        原理:

  1. 对于二级索引的插入/修改,不直接去磁盘更新,而是先记录到 Change Buffer。
  2. 之后在一定条件(比如页被读取进内存,或系统空闲时)才真正合并到磁盘上的二级索引页。


为什么只针对二级索引(非主键索引)?

  1. 因为主键索引(聚集索引)必须保证实时一致性。
  2. 二级索引允许延迟一致,所以可以先缓存在 Change Buffer。

一级索引(主索引):叶子节点存整行

二级索引(辅助索引):叶子节点存主键id,查询时需要回主键索引再拿数据

CREATE TABLE user (id INT PRIMARY KEY,       -- 主键,主索引name VARCHAR(50),age INT,email VARCHAR(50),INDEX idx_name (name)      -- 二级索引
);
--id 是 主索引(一级索引):--叶子节点:存的是整行数据,比如 {id=1, name="张三", age=20, email="xx@xx.com"}--name 是 辅助索引(二级索引):--叶子节点:只存 {name="张三", id=1}--如果通过 name 查找,还需要根据 id 再去主索引回表拿到完整那一行。
1.8 覆盖索引

查询的数据只需要索引里的字段,不用回表到原表,因此速度更快

CREATE INDEX idx_name_age ON users(name, age);SELECT name, age FROM users WHERE name = 'Tom'; -- 覆盖索引
--因为 name 和 age 都在 idx_name_age 这个索引里,不需要回表SELECT name FROM users WHERE name = 'Tom';     -- 回表了
1.9 最左匹配规则

组合索引在查询时,会优先用最左边的列开始匹配,从左到右连续匹配才能用上索引

CREATE INDEX idx_user_name_age ON users(name, age);SELECT * FROM users WHERE name = 'Tom';      --  用上索引
SELECT * FROM users WHERE name = 'Tom' AND age = 18; --  用上索引
SELECT * FROM users WHERE age = 18;           -- 用不了索引(跳过了最左的 name)
1.10 索引下推

        目的:减少回表次数,减少server层和引擎层的交互次数,从而提升查询次数

        对象:辅助索引(二级索引),普通索引和联合索引场景居多

        流程:将索引添加判断推到存储引擎中过滤数据,最终由存储引擎进行数据汇总返回给server层,减少了server层和引擎层的交互次数。

1.11 索引失效

        一些不合理的 SQL 写法,会导致原本可以使用的索引失效,导致全表扫描

  • select ... where A and B 若 A 和 B 中有一个不包含索引,则索引失效;
  • 索引字段参与运算,则索引失效;
  • 索引字段发生隐式转换,则索引失效;
  • LIKE 模糊查询,通配符 % 开头,则索引失效;
  • 在索引字段上使用 select * from user where name like NOT <> != 索引失效;如果判断 id <> 0 则修改为
  • 组合索引中,没使用第一列索引(最左匹配规则),索引失效;
1.12 索引原则
  • 查询频次较高且数据量大的表建立索引;索引选择使用频次较高,过滤效果好的列或者组合;
  • 使用短索引;节点包含的信息多,较少磁盘 IO 操作;比如: smallint , tinyint ;
  • 对于很长的动态字符串,考虑使用前缀索引;
  • 对于组合索引,考虑最左侧匹配原则、覆盖索引;
  • 尽量选择区分度高的列作为索引;
  • 尽量扩展索引,在现有索引的基础上,添加复合索引;最多 6 个索引
  • 不要 s elect *; 尽量只列出需要的列字段;方便使用覆盖索引;
  • 可选:开启自适应 hash 索引或者调整 change buffer;

2. SQL 语句速度慢处理

2.1 找到 SQL 语句
  •         show processlist
  •         开启慢查询日志
2.2 分析SQL
  •         索引     优化  where/group by/order by
  •         SQL 语句        将 in 和 not in 优化成联合查询  --->   减少联合查询

相关文章:

MySQL索引原理以及SQL优化(二)

目录 1. 索引与约束 1.1 索引是什么 1.2 索引的目的 1.3 索引分类 1.3.1 数据结构 1.3.2 物理存储 1.3.3 列属性 1.3.4 列的个数 1.4 主键的选择 1.5 索引使用场景 1.6 索引的底层实现 1.6.1 索引存储 1.6.2 页 1.6.3 B 树 1.6.4 B 树层高问题 1.6.5 自增 id 1.7 innod…...

MATLAB中矩阵和数组的区别

文章目录 前言环境配置1. 数据结构本质2. 运算规则&#xff08;1&#xff09;基本运算&#xff08;2&#xff09;特殊运算 3. 函数与操作4. 高维支持5. 创建方式 前言 在 MATLAB 中&#xff0c;矩阵&#xff08;Matrix&#xff09; 和 数组&#xff08;Array&#xff09; 的概…...

Desfire Ev1\Ev2\Ev3卡DES\3K3DES\AES加解密读写C#示例源码

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?spma21dvs.23580594.0.0.1d292c1bYhsS9c&ftt&id917152255720 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using S…...

MySQL核心内容【完结】

MySQL核心内容 文章目录 MySQL核心内容1.MySQL核心内容目录2.MySQL知识面扩展3.MySQL安装4.MySQL配置目录介绍Mysql配置远程ip连接 5.MySQL基础1.MySQL数据类型1.数值类型2.字符串类型3.日期和时间类型4.enum和set 2.MySQL运算符1.算数运算符2.逻辑运算符3.比较运算符 3.MySQL完…...

C++类和对象进阶 —— 与数据结构的结合

&#x1f381;个人主页&#xff1a;工藤新一 &#x1f50d;系列专栏&#xff1a;C面向对象&#xff08;类和对象篇&#xff09; &#x1f31f;心中的天空之城&#xff0c;终会照亮我前方的路 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 文章目录 […...

Django之账号登录及权限管理

账号登录及权限管理 目录 1.登录功能 2.退出登录 3.权限管理 4.代码展示合集 这篇文章, 会讲到如何实现账号登录。账号就是我们上一篇文章写的账号管理功能, 就使用那里面已经创建好的账号。这一次登录, 我们分为三种角色, 分别是员工, 领导, 管理员。不同的角色, 登录进去…...

从一城一云到AI CITY,智慧城市进入新阶段

AI将如何改变城市面貌&#xff1f;AI能否为城市创造新的商业价值&#xff1f;AI的落地应用将对日常生活有什么样的影响&#xff1f; 几乎在每一场和城市发展相关的论坛上&#xff0c;都会出现以上几个问题。城市既是AI技术创新融合应用的综合性载体&#xff0c;普罗大众对AI产…...

Oracle数据库DBF文件收缩

这两天新部署了一套系统&#xff0c;数据库结构保持不变&#xff0c;牵扯导出表结构还有函数&#xff0c;图省事就直接新建用户&#xff0c;还原数据库了。然后咔咔咔&#xff0c;一顿删除delete&#xff0c;truncate&#xff0c;发现要不就是表删了&#xff0c;还有num_rows&a…...

EXCEL中嵌入其他表格等文件

在EXCEL中嵌入其他表格 先放链接&#xff1a;https://jingyan.baidu.com/article/295430f11708c34d7e00509a.html 步骤如下&#xff1a; 1、打开一个需要嵌入新表格的excel表。 2、切换至“插入”菜单中&#xff0c;单击选择“对象”。 3、如下图所示&#xff0c;会弹出“对象…...

21. LangChain金融领域:合同审查与风险预警自动化

引言&#xff1a;当AI成为24小时不眠的法律顾问 2025年某商业银行的智能合同系统&#xff0c;将百万级合同审查时间从平均3周缩短至9分钟&#xff0c;风险条款识别准确率达98.7%。本文将基于LangChain的金融法律框架&#xff0c;详解如何构建合规、精准、可追溯的智能风控体系…...

Springboot使用事件流调用大模型接口

什么是事件流 事件流&#xff08;Event Stream&#xff09; 是一种处理和传递事件的方式&#xff0c;通常用于系统中的异步消息传递或实时数据流。在事件驱动架构&#xff08;Event-Driven Architecture&#xff09;中&#xff0c;事件流扮演着至关重要的角色。 事件流的概念…...

计算机网络--2

TCP三次握手 TCP连接为什么需要三次握手 1. 由于网络情况复杂,可能会出现丢包现象,如果第二次握手的时候服务器就认为这个端口可用,然后一直开启,但是如果客户端未收到服务器发送的回复,那么就会重新发送请求,服务器就会重新开启一个端口连接,这样就会浪费一个端口。 三…...

【已解决】WORD域相关问题;错误 未找到引用源;复制域出错;交叉引用域到底是个啥

&#xff08;微软赶紧倒闭 所有交叉引用域&#xff0c;有两个状态&#xff1a;1.锁定。2.手动。可通过编辑->链接查看。 “锁定”状态域的能力&#xff1a; 1. 导出PDF格式稳定&#xff08;【已解决】WORD导出PDF时&#xff0c;参考文献上标自动被取消/变为正常文本_word…...

尤雨溪宣布:Vue 生态正式引入 AI

在前端开发领域,Vue 框架一直以其易用性和灵活性受到广大开发者的喜爱。 而如今,Vue 生态在人工智能(AI)领域的应用上又迈出了重要的一步。 尤雨溪近日宣布,Vue、Vite 和 Rolldown 的文档网站均已添加了llms.txt文件,这一举措旨在让大型语言模型(LLM)更方便地理解这些…...

蓝桥杯第十六届c组c++题目及个人理解

本篇文章只是部分题目的理解&#xff0c;代码和思路仅供参考&#xff0c;切勿当成正确答案&#xff0c;欢迎各位小伙伴在评论区与博主交流&#xff01; 题目&#xff1a;2025 题目解析 核心提取 要求的数中至少有1个0、2个2、1个5 代码展示 #include<iostream> #incl…...

【MVCP】基于解纠缠表示学习和跨模态-上下文关联挖掘的多模态情感分析

多处可看出与同专栏下的DCCMCI很像 abstract 多模态情感分析旨在从多模态数据中提取用户表达的情感信息,包括语言、声学和视觉线索。 然而,多模态数据的异质性导致了模态分布的差异,从而影响了模型有效整合多模态互补性和冗余性的能力。此外,现有的方法通常在获得表征后直…...

Go语言--语法基础4--基本数据类型--类型转换

Go 编程语言中 if 条件语句的语法如下&#xff1a; 1 、基本形式 if 布尔表达式 { /* 在布尔表达式为 true 时执行 */ } If 在布尔表达式为 true 时&#xff0c;其后紧跟的语句块执行&#xff0c;如果为 false 则 不执行。 package main import "fmt"…...

硬件工程师笔记——电子器件汇总大全

目录 1、电阻 工作原理 欧姆定律 电阻的物理本质 一、限制电流 二、分压作用 三、消耗电能&#xff08;将电能转化为热能&#xff09; 2、压敏电阻 伏安特性 1. 过压保护 2. 电压调节 3. 浪涌吸收 4. 消噪与消火花 5. 高频应用 3、电容 工作原理 &#xff08;…...

微软推动智能体协同运作:支持 A2A、MCP 协议

今日凌晨&#xff0c;微软宣布 Azure AI Foundry 和 Microsoft Copilot Studio 两大开发平台支持最新 Agent 开发协议 A2A&#xff0c;并与谷歌合作开发扩大该协议&#xff0c;这一举措对智能体赛道意义重大。 现状与变革意义 当前智能体领域类似战国时代&#xff0c;各家技术…...

Qt模块化架构设计教程 -- 轻松上手插件开发

概述 在软件开发领域,随着项目的增长和需求的变化,保持代码的可维护性和扩展性变得尤为重要。一个有效的解决方案是采用模块化架构,尤其是利用插件系统来增强应用的功能性和灵活性。Qt框架提供了一套强大的插件机制,可以帮助开发者轻松实现这种架构。 模块化与插件系统 模…...

Linxu实验五——NFS服务器

一.NFS服务器介绍 NFS服务器&#xff08;Network File System&#xff09;是一种基于网络的分布式文件系统协议&#xff0c;允许不同操作系统的主机通过网络共享文件和目录3。其核心作用在于实现跨平台的资源透明访问&#xff0c;例如在Linux和Unix系统之间共享静态数据&#…...

RV1126 ROS2环境交叉编译及部署(基于官方Docker)

RV1126 ROS2环境交叉编译及部署(基于官方Docker) 0 前言1 SDK源码更新1.1 启动Docker容器1.2 更新SDK源码1.3 SDK更新问题2 ROS2编译配置3 Buildroot rootfs编译ROS2的依赖包3.1 编译问题解决4 使用Docker交叉编译ROS24.1 准备Linux(Ubuntu) PC机的依赖环境4.1.1 Ubuntu PC机…...

20242817李臻《Linux⾼级编程实践》第9周

20242817李臻《Linux⾼级编程实践》第9周 一、AI对学习内容的总结 第十章 Linux下的数据库编程 10.1 MySQL数据库简介 MySQL概述&#xff1a;MySQL是一个开源的关系型数据库管理系统&#xff0c;最初由瑞典MySQL AB公司开发&#xff0c;后经SUN公司收购&#xff0c;现属于O…...

查看YOLO版本的三种方法

查看YOLO版本的三种方法&#xff1a; 一、通过命令行直接查询 使用Python交互式查询&#xff1a; from ultralytics import __version__ print(__version__) # 示例输出: 11.0.5二、检查PyTorch环境兼容性 import torch, ultralytics print(f"PyTorch: {torch.__versi…...

双流 JOIN 与维表 JOIN 的区别

Flink 双流 JOIN 与维表 JOIN 的区别 1. 数据关联的实时性与更新机制 维表 JOIN 基于当前快照 关联外部存储&#xff08;如 MySQL、HBase&#xff09;的 最新状态&#xff0c;仅反映处理时间的当前数据&#xff0c;历史结果不会随维表更新而修正。无状态回溯 无法关联历史版…...

MySQL OCP和Oracle OCP怎么选?

近期oracle 为庆祝 MySQL 数据库发布 30 周年&#xff0c;Oracle 官方推出限时福利&#xff1a;2025 年 4 月 20 日至 7 月 31 日期间&#xff0c;所有人均可免费报考 MySQL OCP&#xff08;Oracle Certified Professional&#xff09;认证考试&#xff08;具体可查看MySQL OCP…...

汽车为什么需要以太网?带宽?实时?

一、传统总线“堵车”&#xff1a;为什么CAN、LIN扛不住了&#xff1f; 1. 带宽危机 案例&#xff1a;一辆L3级自动驾驶汽车每秒产生约4GB数据&#xff08;激光雷达摄像头&#xff09;&#xff0c;而CAN FD总线最高仅8Mbps。若用CAN传输&#xff0c;需 500秒才能传完1秒的数据—…...

开源分享:TTS-Web-Vue系列:SSML格式化功能与高级语音合成

&#x1f3af; 本文是TTS-Web-Vue系列的第十二篇文章&#xff0c;重点介绍项目新增的SSML格式化功能以及SSML在语音合成中的应用。通过自动格式化和实时预览&#xff0c;我们显著提升了SSML编辑体验&#xff0c;让用户能够更精确地控制语音合成的细节&#xff0c;实现更自然、更…...

[人机交互]理解界面对用户的影响

零.重点 – 什么是情感因素 – 富有表现力的界面 – 用户的挫败感 – 拟人化在交互设计中的应用 – 虚拟人物&#xff1a;代理 一.什么是情感方面 情感是指某事物对心理造成的一种状态 二.计算机科学中存在的两个相关的研究领域 2.1情感计算 机器如何能感知其他代理的情感&…...

FAST-LIO笔记

1.FAST-LIO FAST-LIO 是一个计算效率高、鲁棒性强的激光-惯性里程计系统。该系统通过紧耦合的迭代扩展卡尔曼滤波器&#xff08;IEKF&#xff09;将激光雷达特征点与IMU数据进行融合&#xff0c;使其在快速运动、噪声较大或环境复杂、存在退化的情况下仍能实现稳定的导航。 1…...