聚簇索引、哈希索引、覆盖索引、索引分类、最左前缀原则、判断索引使用情况、索引失效条件、优化查询性能
聚簇索引
聚簇索引像一本按目录排版的书,用空间换时间,适合读多写少的场景。设计数据库时,主键的选择(如自增ID vs 随机UUID)会直接影响聚簇索引的性能。
什么是聚簇索引?
-
数据即索引:聚簇索引的叶子节点直接存储整行数据(而不是指向数据的指针),因此表中的数据行物理上按索引键的顺序存储。
-
唯一性:一张表只能有一个聚簇索引(就像一本书只能按一种顺序排版)。
类比生活场景:
-
普通索引(非聚簇索引):像一本书末尾的“关键词索引”,每个关键词后标注页码,你需要先查索引,再翻到对应页。
-
聚簇索引:像书的目录本身,章节内容严格按照目录顺序排版。找某一章时,直接按目录顺序翻到对应页即可,无需二次跳转。
优点:
-
查询快:范围查询(如
WHERE id BETWEEN 1000 AND 2000
)效率高,因为数据在磁盘上是连续的。 -
排序快:如果按聚簇索引的字段排序(如主键),数据库可以直接按物理顺序读取,无需额外操作。
缺点:
-
插入/更新慢:新增数据时,如果新数据需要插入到中间位置,可能导致数据页分裂(类似电话簿插页时需要撕开重新装订)。
-
依赖主键设计:如果主键设计不合理(例如用随机UUID),可能导致存储碎片化,降低性能。
常见应用:
-
主键默认是聚簇索引(如MySQL的InnoDB引擎)。
-
适合频繁查询的字段:比如用户表的用户ID、订单表的订单时间。
哈希索引
哈希索引通过哈希函数将数据的关键字(如手机号)直接转换成存储位置,适合快速等值查找,但无法支持范围查询或排序。
什么是哈希索引?
-
哈希函数:将任意长度的输入(如字符串、数字)转换成固定长度的哈希值(如
0x3A7F
)。 -
直接定位数据:通过哈希值直接找到数据在内存或磁盘上的存储位置,无需遍历。
类比生活场景:
-
普通索引(如B树索引):像图书馆按书名首字母分类的书架,需要按顺序查找。
-
哈希索引:像快递柜的编号,输入手机号就能秒定位到具体柜子。
优点:
-
查询极快:等值查询(如
WHERE id = 123
)的时间复杂度接近 O(1)。 -
无数据顺序要求:适合随机读写场景(如用户登录、缓存)。
缺点:
-
不支持范围查询:无法高效执行
WHERE id > 100
或ORDER BY
。 -
哈希冲突:不同关键字可能生成相同的哈希值(如手机号A和B被分配到同一个柜子),需要额外处理(如链表串联)。
-
动态扩容成本高:数据量增长时,哈希表可能需要重新分配空间并重新计算所有哈希值。
常见应用:
-
内存数据库:如Redis的键值存储。
-
快速查找表:如用户Session、短链映射。
-
数据库的Hash Join:关联查询时临时使用哈希表加速。
哈希索引 vs B树索引
覆盖索引
使用普通索引时通常需要两步1.查找索引2.回表操作
使用覆盖索引则通常是直接从索引中直接获取数据,也就是省略了回表步骤
覆盖索引的优点:
减少IO操作:查询时直接从索引中获取数据,无需访问表中的数据行,显著提高查询性能,特别是在数据量很大或者磁盘IO成本很高。
索引中的数据:索引通常由被索引的列及其指向的行标识符组成,覆盖索引会存储更多的数据以满足查询需求
索引分类
按物理存储方式分类:
聚簇索引、非聚簇索引
按功能分类:
唯一索引、普通索引、全文索引、空间索引
按索引结构分类:
BTree索引、Hash索引
按应用场景分类:
单列索引、复合索引、覆盖索引
按存储引擎支持情况分类:
- InnoDB 支持 B-Tree 索引、唯一索引、全文索引(从 MySQL 5.6 开始)。
- MyISAM 支持 B-Tree 索引、全文索引。
- Memory 支持 Hash 索引和 B-Tree 索引。
最左前缀原则
“最左前缀原则”是数据库(尤其是 MySQL 中)在使用复合索引时的一条重要规则,它规定:在复合索引中,查询条件必须从索引的最左侧开始,连续地使用索引列,才能使该索引被有效利用。
如果创建了一个复合索引(col1, col2, col3),当使用索引时必须是从左到右使用,如果跳过前面的去使用后面的话就会导致索引失效。
-
提高查询效率:
通过利用复合索引,数据库可以直接定位到符合条件的数据行,减少扫描数据量,显著提升查询速度。 -
优化设计索引:
在设计复合索引时,应考虑查询的常用模式,将最常用的查询条件放在索引的最左侧。例如,如果大多数查询都是根据col1
进行过滤,再根据col2
进行细分,那么将col1
放在最前面可以最大程度发挥索引优势。 -
避免索引失效:
如果查询条件没有覆盖复合索引的最左前缀,那么索引将无法被利用,这样会导致查询性能下降。因此在编写 SQL 语句和设计索引时,必须充分考虑这一原则。
= 和 IN 条件的顺序无关性:
对于等值查询(=
)和 IN
查询,条件的顺序不影响索引使用。MySQL 优化器会自动调整条件顺序以匹配索引的最左前缀。
WHERE b = 2 AND a = 1 AND c = 3;
索引 (a, b, c)
:
-
优化器会将条件重排为
a = 1 AND b = 2 AND c = 3
,完全匹配索引。 -
即使条件顺序不同,索引仍能覆盖所有列。
判断索引使用情况
以MySQL为例:
查看索引的使用统计:
-- 查看表的索引使用情况(需开启性能模式)
SELECT * FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_NAME = 'your_table';-- 查看索引的碎片化程度
SHOW INDEX FROM your_table;
分析查询是否使用索引:
EXPLAIN SELECT * FROM your_table WHERE indexed_column = 'value';
-
关键字段:
-
type
:ref
或range
表示使用了索引。 -
key
:显示实际使用的索引名称。 -
rows
:扫描的行数,值越小效率越高。
-
优化数据库表
OPTIMIZE TABLE table_name;
作用
-
回收未使用的磁盘空间:
删除大量数据后,会有空闲的磁盘空间,OPTIMIZE TABLE
可以释放这些空间。 -
重新组织索引:
对于索引密集的表,优化索引布局可以提高查询性能。 -
提高数据读取速度:
通过整理数据和索引,可以减少磁盘 I/O 操作,提升读取速度。
索引失效条件
使用范围查询、不满足最左前缀原则、使用了不等于运算符、使用函数或表达式、隐式类型转换、模糊查询以通配符开头、使用OR、查询返回过多数据、数据分布不均匀、索引未覆盖查询(无法使用覆盖索引)、表统计信息不准确(数据库优化器依赖表的统计信息进行查询计划的选择。如果统计信息过时或不准确,可能导致错误地放弃索引)、使用了不支持索引的操作
如果避免索引失效:
- 遵循最左前缀原则,合理设计索引。
- 避免在索引列上使用函数、表达式或隐式类型转换。
- 在模糊查询中尽量避免
%
开头。 - 对
OR
条件进行优化,例如重构为UNION ALL
。 - 确保表的统计信息及时更新。
- 使用覆盖索引,减少回表查询。
- 确保查询返回的数据量较少。
优化查询性能的方法
减少请求的数据量:
- 只返回必要的列,最好不要使用SELECT *语句、使用LIMIT语句来限制返回的数据。
- 缓存重复查询的数据:使用缓存可以避免在数据库中进行查询,特别是在要查询的数据经常被查询时,使用缓存会极大的提升查询性能
减少服务器端扫描的行数:
- 使用索引来覆盖查询
- 避免索引失效
查询重构优化:
- 避免使用复杂的JOIN和子查询
- 批量操作代替循环操作(循环执行单条 SQL 会增加网络和事务开销。)
-- 不推荐:循环插入 INSERT INTO logs (message) VALUES ('log1'); INSERT INTO logs (message) VALUES ('log2');-- 推荐:批量插入 INSERT INTO logs (message) VALUES ('log1'), ('log2');
数据库配置优化:
- 调整缓冲区大小
-- 增加 InnoDB 缓冲池大小(通常设为物理内存的 70%~80%) SET GLOBAL innodb_buffer_pool_size = 4G;
- 配置数据库连接池(避免短连接:使用连接池(如 HikariCP、Druid)复用连接。
参数调优:设置合理的最大连接数和空闲超时时间)
架构层面优化:
读写分离
-
主库:处理写操作和高一致性读。
-
从库:处理读操作,通过复制同步数据。
分库分表
-
垂直分表:将大字段(如 TEXT、BLOB)拆分到独立表。
-
水平分库:按业务分库(如订单库、用户库)。
-
水平分表:按哈希或范围分表(如
user_0
、user_1
)。
相关文章:

聚簇索引、哈希索引、覆盖索引、索引分类、最左前缀原则、判断索引使用情况、索引失效条件、优化查询性能
聚簇索引 聚簇索引像一本按目录排版的书,用空间换时间,适合读多写少的场景。设计数据库时,主键的选择(如自增ID vs 随机UUID)会直接影响聚簇索引的性能。 什么是聚簇索引? 数据即索引:聚簇索引…...

OpenAI 实战进阶教程 - 第四节: 结合 Web 服务:构建 Flask API 网关
目标 学习将 OpenAI 接入 Web 应用,构建交互式 API 网关理解 Flask 框架的基本用法实现 GPT 模型的 API 集成并返回结果 内容与实操 一、环境准备 安装必要依赖: 打开终端或命令行,执行以下命令安装 Flask 和 OpenAI SDK: pip i…...

python的pre-commit库的使用
在软件开发过程中,保持代码的一致性和高质量是非常重要的。pre-commit 是一个强大的工具,它可以帮助我们在提交代码到版本控制系统(如 Git)之前自动运行一系列的代码检查和格式化操作。通过这种方式,我们可以确保每次提…...

架构技能(四):需求分析
需求分析,即分析需求,分析软件用户需要解决的问题。 需求分析的下一环节是软件的整体架构设计,需求是输入,架构是输出,需求决定了架构。 决定架构的是软件的所有需求吗?肯定不是,真正决定架构…...

Linux环境下的Java项目部署技巧:安装 Nginx
Nginx 的简介: Nginx 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP / POP3 / SMTP 代理服务器。它可以作为网站静态资源的 web 服务器,也可以作为其他应用服务器的反向代理服务器。同时, Nginx 还具有负载均衡的功能。 N…...
前端 Vue 性能提升策略
一、引言 前端性能优化是确保 Web 应用快速响应和流畅用户体验的关键。对于使用 Vue.js 构建的应用,性能优化不仅涉及通用的前端技术,还包括针对 Vue 特性的特定优化措施。本文将从多个方面探讨如何全面提升前端和 Vue 应用的性能。 二、前端性能优化基础 1. 减少初始加载…...

深入理解linux中的文件(上)
1.前置知识: (1)文章 内容 属性 (2)访问文件之前,都必须打开它(打开文件,等价于把文件加载到内存中) 如果不打开文件,文件就在磁盘中 (3&am…...

Unity特效插件GodFX
2022Unity安装使用方法,将MinDrawer.cs文件MinAttribute改成UnityEngine.PostProcessing.MinAttribute 参考链接: Unity3D特效插件GodFX使用教程_哔哩哔哩_bilibili...
从 C 到 C++:理解结构体中字符串的存储与操作
对于刚入门 C/C 的程序员来说,字符串的存储和操作可能是个容易混淆的知识点。在 C 中,std::string 提供了非常友好的接口,我们可以轻松地在结构体中使用字符串类型,无需关注底层细节。然而,在 C 语言中,字符…...

Linux进阶——时间服务器
NTP是网络时间协议(network time protocol)的简称(应用层的协议),通过UDP123端口进行网络时钟同步。 Chrony是一个开源自由的网络时间协议NTP的客户端和服务器软件。它能让计算机保持系统时钟与时钟服务器(…...
力扣 295. 数据流的中位数
🔗 https://leetcode.cn/problems/find-median-from-data-stream/ 题目 数据流中不断有数添加进来,add 表示添加数据,find 返回数据流中的中位数 思路 大根堆存储数据流中偏小的数据小根堆存储数据流中偏大的数据若当前的 num 比大根堆的…...

【Linux】进程状态和优先级
个人主页~ 进程状态和优先级 一、进程状态1、操作系统进程状态(一)运行态(二)阻塞态(三)挂起态 2、Linux进程状态(一)R-运行状态并发执行 (二)S-浅度睡眠状态…...

携程Java开发面试题及参考答案 (200道-上)
说说四层模型、七层模型。 七层模型(OSI 参考模型) 七层模型,即 OSI(Open System Interconnection)参考模型,是一种概念模型,用于描述网络通信的架构。它将计算机网络从下到上分为七层,各层的功能和作用如下: 物理层:物理层是计算机网络的最底层,主要负责传输比特流…...

Docker 部署教程jenkins
Docker 部署 jenkins 教程 Jenkins 官方网站 Jenkins 是一个开源的自动化服务器,主要用于持续集成(CI)和持续交付(CD)过程。它帮助开发人员自动化构建、测试和部署应用程序,显著提高软件开发的效率和质量…...

深入理解开放寻址法中的三种探测序列
一、引言 开放寻址法是解决散列表中冲突的一种重要方法,当发生冲突(即两个不同的键通过散列函数计算得到相同的散列值)时,它会在散列表中寻找下一个可用的存储位置。而探测序列就是用于确定在发生冲突后,依次尝试哪些…...
图像噪声处理技术:让图像更清晰的艺术
在这个数字化时代,图像作为信息传递的重要载体,其质量直接影响着我们的视觉体验和信息解读。然而,在图像采集、传输或处理过程中,难免会遇到各种噪声干扰,如高斯噪声、椒盐噪声等,这些噪声会降低图像的清晰…...

linux运行级别
运行级别:指linux系统在启动和运行过程中所处的不同的状态。 运行级别之间的切换:init (级别数) 示例: linux的运行级别一共有7种,分别是: 运行级别0:停机状态 运行级别1:单用户模式/救援模式…...
深入剖析Electron的原理
Electron是一个强大的跨平台桌面应用开发框架,它允许开发者使用HTML、CSS和JavaScript来构建各种桌面应用程序。了解Electron的原理对于开发者至关重要,这样在设计应用时能更合理,遇到问题也能更准确地分析和解决。下面将从多个方面深入剖析E…...

C++ 游戏开发:完整指南
目录 什么是游戏开发? 为什么选择 C 进行游戏开发? C 游戏开发:完整指南 1. 理解游戏开发的基础 2. 学习游戏引擎 3. 精通 C 进行游戏开发 4. 学习数学在游戏开发中的应用 5. 探索图形编程 6. 专注于游戏开发的某一领域 7. 通过游戏项目进行实…...
WebForms SortedList 深度解析
WebForms SortedList 深度解析 引言 在Web开发领域,对于数据结构的理解与应用至关重要。其中,SortedList类在WebForms中是一个常用的数据结构,它能够帮助开发者高效地管理有序数据集合。本文将深入解析SortedList类在WebForms中的应用,包括其基本概念、常用方法、性能特点…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...

C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...

【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...

Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...