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

news2025/7/14 18:05:25

目录

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 优化成联合查询  --->   减少联合查询

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

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

相关文章

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.代码展示合集 这篇文章, 会讲到如何实现账号登录。账号就是我们上一篇文章写的账号管理功能, 就使用那里面已经创建好的账号。这一次登录, 我们分为三种角色, 分别是员工, 领导, 管理员。不同的角色, 登录进去…

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

尤雨溪宣布: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…

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

目录 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;各家技术…

Linxu实验五——NFS服务器

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

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

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

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

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

FAST-LIO笔记

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

软考中级软件设计师——UML(统一建模语言)篇

UML的词汇表包含3种构造块:事物、关系和图。事物是对模型中最具有代表性的成分的抽象;关系把事物结合在一起;图聚集了相关的事物。 一、事物 UML 事物是模型中的基本元素&#xff0c;分为 结构事物、行为事物、分组事物、注释事物。 1. 结构事物 类&#xff08;Class&#x…

TSN网络与DIOS融合:破解煤矿井下电力系统越级跳闸难题

一、引言 1.1 研究背景与意义 在现代煤矿生产中&#xff0c;井下电力系统作为整个煤矿生产的动力核心&#xff0c;其重要性不言而喻。煤矿井下的各类机械设备&#xff0c;如采煤机、刮板输送机、通风机、排水泵等&#xff0c;都依赖稳定的电力供应才能正常运行。电力系统的稳定…

SierraNet协议分析使用指导[RDMA]| 如何设置 NVMe QP 端口以进行正确解码

在解码RoCEv2数据包&#xff08;包括TCP RDMA和RoCE RDMA&#xff09;时&#xff0c;若捕获的跟踪数据无法正确解码&#xff0c;通常需要执行特定的解码步骤。对于RoCE RDMA跟踪数据的处理&#xff0c;分析器主要采用两种方式获取必要信息以实现数据包解码&#xff1a; 首先&am…