深度整理总结MySQL——索引正确使用姿势
索引正确使用姿势
- 前言
- MySQL索引优缺点分析
- ✅ 索引的优势
- ⚠️ 索引的代价
- 如何合理建立索引?——关键原则总结
- 重要的优化机制
- 索引覆盖——通俗的方式讲解
- 索引下推
- 索引跳跃式扫描
前言
这篇文章是补充一些基本概念和实战的一些使用建议.
MySQL索引优缺点分析
✅ 索引的优势
1️⃣ 提升查询性能:索引能够显著加快数据查询速度,数据量越大,效果越明显。
2️⃣ 保证数据唯一性:唯一索引(UNIQUE)可以确保数据表中的某些字段不出现重复值,无需额外添加唯一性约束。
3️⃣ 优化分组与排序:索引可以加速 GROUP BY 和 ORDER BY 语句,减少分组与排序的计算开销。
4️⃣ 提升关联查询性能:在多表 JOIN 操作时,合理的索引(如主键索引、外键索引)能够大幅提高查询效率。
5️⃣ 优化范围查询:B+Tree 索引结构天然有序,使 BETWEEN、>、<、>=、<= 这类范围查询更加高效。
6️⃣ 提高数据库吞吐量:优化 SQL 执行效率,减少查询时间,从而提升数据库整体的吞吐能力。
⚠️ 索引的代价
1️⃣ 占用额外存储空间:索引会生成额外的磁盘文件,尤其是大数据量场景下,索引存储空间可能远超数据本身。
2️⃣ 影响写入性能:数据的增、删、改操作需要同步维护索引,导致写入性能下降。
3️⃣ 增加索引维护成本:每次 INSERT、DELETE 或 UPDATE 操作都可能引发索引的重构或调整,影响整体执行效率。
📌 结论:索引不是越多越好,而是要合理使用!
尽管索引带来的优势远大于劣势,但并不是索引越多越好。
过多的索引不仅会占用大量存储,还可能影响写入性能,因此合理规划索引策略,结合业务场景进行优化,才是最佳实践! 🚀
如何合理建立索引?——关键原则总结
在设计索引时,仅仅考虑某个字段是否频繁出现在查询条件中是不够的。
一个优秀的索引策略需要综合考虑查询模式、数据特征以及索引类型,以实现最佳性能。以下是建立索引时需要遵循的重要原则:
1️⃣ 针对查询频率高的字段建立索引
对于经常用于 WHERE 条件的字段,应考虑创建索引,以加速查询。
2️⃣ 关联字段必须建立索引
主键(Primary Key)、外键(Foreign Key)及 JOIN 连接字段 应创建索引,以提升多表查询性能。
3️⃣ 选择区分度高的字段作为索引
索引字段的值应该尽可能具有高区分度(Cardinality),即唯一值较多,能有效减少查询扫描的行数。例如,索引 身份证号 是有效的,但索引 性别 作用不大。
4️⃣ 避免索引过长,可使用前缀索引
如果字段值较长(如 VARCHAR(255)),应避免全文索引,可以考虑前缀索引(PREFIX INDEX),这样既能提高查询效率,又能节省存储空间。
5️⃣ 联合索引需遵循最左前缀原则
创建联合索引时,应按照查询使用频率 和 过滤效果 来确定字段顺序。索引的匹配遵循最左前缀法则,即查询条件必须从索引的最左字段开始,否则索引可能无法生效。
6️⃣ 对于排序、分组字段建立索引
ORDER BY、GROUP BY 及范围查询(BETWEEN、>、<、>=、<=) 的字段适合建立索引,利用索引的有序性 可以加快查询。
7️⃣ 唯一索引不用于排序时,可考虑 Hash 结构
如果某字段仅用于唯一性约束,且不会用于范围查询或排序,可以使用 Hash 索引(如 MEMORY 表中的 HASH INDEX),查询性能更高。
8️⃣ 联合索引优于多个单列索引
相较于多个独立索引,联合索引(Composite Index) 更具优势,能有效减少回表查询(避免 Using filesort 和 Using temporary),提高查询效率。
📌 结论:索引优化是门技术活!
合理的索引策略不是盲目加索引,而是结合业务场景,选择合适的索引字段和索引类型,以最大化查询性能,同时避免过多索引带来的存储和维护开销。
重要的优化机制
索引覆盖——通俗的方式讲解
我们先从回表查询 说起——想象一下,你去图书馆查一本书的内容。
回表查询的情况:
你想知道 房间号、房型、价格、入住人姓名,但是前台的客房查询系统(索引) 只存了 房间号和房型,而入住人姓名和价格在纸质登记表(主键索引数据)里。
你先从 索引 里查到房间号,再去 纸质登记表 里翻找到对应的信息,才能拿到最终结果。
这个过程就类似 MySQL 先用索引查 ID,再回表查完整数据,也就是 回表查询。
索引覆盖的情况:
如果你 只想查房间号和房型,那么前台系统(索引) 里已经包含了这些信息,你直接就能得到结果,不用再翻纸质登记表(回表)。
- 这个时候,你查的信息 完全被索引覆盖,数据库不需要再去表里查完整数据,查询效率更高
举个例子,假设有个 hotel_rooms 表,字段如下:
room_id(主键) | room_type | price | guest_name |
---|---|---|---|
101 | 豪华大床房 | 500 | 张三 |
102 | 标准双床房 | 300 | 李四 |
🚨 回表查询
SELECT * FROM hotel_rooms WHERE room_type = '豪华大床房';
🔹 MySQL 先通过索引找到符合条件的 room_id,然后还要回表查 price 和 guest_name,才能返回完整数据。
✅ 使用索引覆盖
SELECT room_id, room_type FROM hotel_rooms WHERE room_type = '豪华大床房';
🔹 这次查询的 room_id 和 room_type 都在索引里,不用回表,直接返回结果! 🔹 索引覆盖成功,查询更快!
📌 总结
索引覆盖就像 前台查询系统,如果你查的信息已经在索引里,直接返回;如果你查的信息不全,就得去翻纸质档案(回表)。
所以,合理设计索引结构,可以大大减少回表,提高查询速度!🚀
索引下推
我们用 酒店前台查询 的例子,和索引覆盖的方式类似.
📚 先来看普通查询(不使用索引下推)
假设你是 酒店前台查询入住的客人,你说:“我想查 住在标准双床房,且价格低于 400 元 的客人信息。”
前台(数据库)是这样做的:
- 先查索引:找到所有 “标准双床房” 的 room_id。
- 回表查询:去登记表(主键索引)里 一个个查 price,筛选出价格 < 400 的房间。
⚠ 问题:索引本来能筛选部分数据,但 price 这个条件要等回表后才能判断,多了一步,效率低!
✅ 使用索引下推优化查询
索引下推 就像前台自己变聪明了,能直接用索引来筛选一部分数据!
“标准双床房 & 价格 < 400” 这两个条件,前台能直接处理一部分,不用都去翻登记表!"
- 先查索引,不仅找 room_type = “标准双床房”,还在索引层先筛选 price < 400 的记录!
- 只对符合条件的 room_id 才回表查询,减少不必要的回表操作。
🚀 优化点:减少了回表次数,提高查询速度!
🛠 结合 SQL 代码
SELECT guest_name FROM hotel_rooms
WHERE room_type = '标准双床房' AND price < 400;
如果 room_type 和 price 都建了索引,MySQL 会使用索引下推:
- 先在索引中筛选:找到 room_type = ‘标准双床房’ 的记录,并且 过滤掉 price >= 400 的行!
- 只对符合条件的记录回表,查 guest_name。
📌 总结
优化方式 | 是否先用索引筛选 price | 回表次数 | 查询速度 |
---|---|---|---|
❌ 没有索引下推 | ❌ 否(先找 room_type,再回表筛选 price) | ⚠ 回表次数多 | ⏳ 慢 |
✅ 使用索引下推 | ✅ 是(索引层先筛选一部分 price) | ✅ 回表次数减少 | 🚀 快 |
索引跳跃式扫描
索引跳跃式扫描 是 MySQL 在查询时的一种优化策略,即使没有使用索引的最左列,它仍然可以部分利用索引来加速查询,而不必完全放弃索引。
📚 直观类比:查找书籍时的跳跃式翻找
假设你去图书馆找一本书,图书馆的书架是按照 类别(Category)+ 书名(Title) 的方式排序的,比如这样:
类别(Category) | 书名(Title) |
---|---|
计算机 | Java入门 |
计算机 | Python进阶 |
计算机 | 数据结构与算法 |
历史 | 中国古代史 |
历史 | 世界历史 |
文学 | 红楼梦 |
文学 | 哈利波特 |
🎯 现实场景:你要找所有书名包含“历史”的书
但问题是:书架是按照类别 + 书名排序的,而你没有指定类别!!!
❌ 传统索引扫描(最左匹配失败,无法利用索引)
如果索引是按 (类别, 书名) 排序的,通常你得先指定类别才能用索引查找。但你没指定类别,所以数据库可能会直接全表扫描,一本一本地检查书名里有没有“历史”两字。
✅ 索引跳跃式扫描(Index Skip Scan)
数据库的优化策略是:
虽然你没指定类别,但系统可以按类别分组,一个类别一个类别地跳跃查找书名:
- 先在“计算机”类别里查找,发现没有“历史”相关书籍,跳过。
- 再到“历史”类别里查找,发现有《中国古代史》《世界历史》,记下来。
- 最后查“文学”类别,发现没有匹配的书,跳过。
这样就不用扫描所有的书,而是按类别跳跃式扫描索引,提高查询效率! 🚀
🔍 代码示例
假设数据库表 t_books:
CREATE TABLE t_books (category VARCHAR(50), -- 书籍类别title VARCHAR(100), -- 书名PRIMARY KEY (category, title) -- 联合索引(按类别+书名排序)
);
你想查所有书名是 “历史” 的书:
SELECT title FROM t_books WHERE title LIKE '%历史%';
🔥 MySQL 可能使用索引跳跃式扫描:
- 先按 category 一组一组地跳跃扫描
- 然后在每组里查 title 是否包含“历史”
这样比全表扫描快很多!
相关文章:
深度整理总结MySQL——索引正确使用姿势
索引正确使用姿势 前言MySQL索引优缺点分析✅ 索引的优势⚠️ 索引的代价 如何合理建立索引?——关键原则总结重要的优化机制索引覆盖——通俗的方式讲解索引下推索引跳跃式扫描 前言 这篇文章是补充一些基本概念和实战的一些使用建议. MySQL索引优缺点分析 ✅ 索引的优势 …...

使用LLaMA Factory踩坑记录
前置条件:电脑显卡RTX 4080 问题:LLaMA-Factory在运行的时候,弹出未检测到CUDA的报错信息 结论:出现了以上的报错,主要可以归结于以下两个方面: 1、没有安装GPU版本的pytorch,下载的是CPU版本…...

亚博microros小车-原生ubuntu支持系列:25 二维码控制运动
二维码识别 安装依赖 pip3 install pyzbarsudo apt install libzbar-dev 在用小车识别之前,先用电脑的摄像头测试下基本的识别 import cv2 import rclpy from rclpy.node import Node import pyzbar.pyzbar as pyzbar import numpy as np from ament_index_pyth…...
基于深度学习的人工智能量化衰老模型构建与全流程应用研究
一、引言 1.1 研究背景与意义 1.1.1 人口老龄化现状与挑战 人口老龄化是当今全球面临的重要社会趋势之一,其发展态势迅猛且影响深远。根据联合国的相关数据,1980 年,全球 65 岁及以上人口数量仅为 2.6 亿,到 2021 年,这一数字已翻番,达到 7.61 亿,而预计到 2050 年,…...

【医院运营统计专题】2.运营统计:医院管理的“智慧大脑”
医院成本核算、绩效管理、运营统计、内部控制、管理会计专题索引 引言 在当今医疗行业快速发展的背景下,医院运营管理的科学性和有效性成为了决定医院竞争力和可持续发展能力的关键因素。运营统计作为医院管理的重要工具,通过对医院各类数据的收集、整理、分析和解读,为医…...

Spring Boot Actuator使用
说明:本文介绍Spring Boot Actuator的使用,关于Spring Boot Actuator介绍,下面这篇博客写得很好,珠玉在前,我就不多介绍了。 Spring Boot Actuator 简单使用 项目里引入下面这个依赖 <!--Spring Boot Actuator依…...
【AI应用】免费的文本转语音工具:微软 Edge TTS 和 开源版 ChatTTS 对比
【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】【AI日记】【读书与思考】【AI应用】 我试用了下Edge TTS,感觉还不错,不过它不支持克隆声音(比如自己的声音) 微软 Edge TTS 和 开源版 ChatTTS 都是免费的 文本转语音&…...

如何在 Qt 中添加和使用系统托盘图标
在 Qt 中实现系统托盘图标是一个常见的需求,尤其是在桌面应用程序中。系统托盘图标可以让应用程序在后台运行时仍然具有可见性,同时避免占用过多的桌面空间。本文将详细介绍如何在 Qt 项目中添加托盘图标,并通过资源系统(.qrc 文件…...

【WB 深度学习实验管理】利用 Hugging Face 实现高效的自然语言处理实验跟踪与可视化
本文使用到的 Jupyter Notebook 可在GitHub仓库002文件夹找到,别忘了给仓库点个小心心~~~ https://github.com/LFF8888/FF-Studio-Resources 在自然语言处理领域,使用Hugging Face的Transformers库进行模型训练已经成为主流。然而,随着模型复…...

基础入门-网站协议身份鉴权OAuth2安全Token令牌JWT值Authirization标头
知识点: 1、网站协议-http/https安全差异(抓包) 2、身份鉴权-HTTP头&OAuth2&JWT&Token 一、演示案例-网站协议-http&https-安全测试差异性 1、加密方式 HTTP:使用明文传输,数据在传输过程中可以被…...

C语言基础系列【3】VSCode使用
前面我们提到过VSCode有多么的好用,本文主要介绍如何使用VSCode编译运行C语言代码。 安装 首先去官网(https://code.visualstudio.com/)下载安装包,点击Download for Windows 获取安装包后,一路点击Next就可以。 配…...

MySQL-5.7.44安装(CentOS7)
目录 1、下载安装包并解压 2、创建数据目录与日志目录 3、设置环境变量 4、刷新环境变量 5、执行初始化 6、创建配置文件目录 7、新建配置文件 8、为安装目录赋予可执行权限 9、创建服务启动脚本 10、启动服务并将启动脚本加入开机自启动 11、查看服务状态 12、创建…...
服务端与多客户端照片的传输,recv,send
一、照片传输 server.c /* * 文件名称:server.c * 创 建 者: * 创建日期:2025年02月07日 * 描 述: */ #include <stdio.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h…...

JS实现灯光闪烁效果
在 JS中,我们可以实现灯光闪烁效果,这里主要用 setInterval 和 clearInterval 两个重要方法。 效果图 源代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>灯闪烁效果<…...
SpringCloud面试题----Nacos和Eureka的区别
功能特性 服务发现 Nacos:支持基于 DNS 和 RPC 的服务发现,提供了更为灵活的服务发现机制,能满足不同场景下的服务发现需求。Eureka:主要基于 HTTP 的 RESTful 接口进行服务发现,客户端通过向 Eureka Server 发送 HT…...

verilog练习:i2c slave 模块设计
文章目录 前言1. 结构2.代码2.1 iic_slave.v2.2 sync.v2.3 wr_fsm.v2.3.1 状态机状态解释 2.4 ram.v 3. 波形展示4. 建议5. 资料总结 前言 首先就不啰嗦iic协议了,网上有不少资料都是叙述此协议的。 下面将是我本次设计的一些局部设计汇总,如果对读者有…...
3.5 Go(特殊函数)
目录 一、匿名函数 1、匿名函数的特点: 2、匿名函数代码示例 2、匿名函数的类型 二、递归函数 1. 递推公式版本 2. 循环改递归 三、嵌套函数 1、嵌套函数用途 2、代码示例 3、作用域 & 变量生存周期 四、闭包 1、闭包使用场景 2、代码示例 五、De…...
Android的MQTT客户端实现
在 Android 平台上实现 MQTT 客户端的完整技术方案,涵盖基础实现、安全连接、性能优化和最佳实践: 一、技术选型与依赖配置 推荐库 Eclipse Paho Android Service(官方维护,支持后台运行) gradle 复制 // build.gradl…...

国产编辑器EverEdit - 编辑辅助功能介绍
1 编辑辅助功能 1.1 各编辑辅助选项说明 1.1.1 行号 打开该选项时,在编辑器主窗口左侧显示行号,如下图所示: 1.1.2 文档地图 打开该选项时,在编辑器主窗口右侧靠近垂直滚动条的地方显示代码的缩略图,如下图所示&…...
WPF 在后台使TextBox失去焦点的方法
在软件设计开发的时候,偶尔会遇到在后台xaml.cs后台中,要将TextBox控件的焦点取消或者使TextBox控件获取焦点,下面介绍讲述一种简单的“只让特定的 TextBox 失去焦点”方法: 前端xaml代码示例: <StackPanel Orientation"…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...

MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...

NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...