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

聚簇索引、哈希索引、覆盖索引、索引分类、最左前缀原则、判断索引使用情况、索引失效条件、优化查询性能

聚簇索引

        聚簇索引像一本按目录排版的书,用空间换时间,适合读多写少的场景。设计数据库时,主键的选择(如自增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';
  • 关键字段:

    • typeref 或 range 表示使用了索引。

    • key:显示实际使用的索引名称。

    • rows:扫描的行数,值越小效率越高。

优化数据库表

OPTIMIZE TABLE table_name;

作用

  1. 回收未使用的磁盘空间
    删除大量数据后,会有空闲的磁盘空间,OPTIMIZE TABLE 可以释放这些空间。

  2. 重新组织索引
    对于索引密集的表,优化索引布局可以提高查询性能。

  3. 提高数据读取速度
    通过整理数据和索引,可以减少磁盘 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_0user_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的客户端和服务器软件。它能让计算机保持系统时钟与时钟服务器&#xff08…...

力扣 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中的应用,包括其基本概念、常用方法、性能特点…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时&#xff0c;发现没有set类的方法&#xff0c;只有get&#xff0c;那么要改变tree值&#xff0c;只能遍历treeData&#xff0c;递归修改treeData的checked&#xff0c;发现无法更改&#xff0c;原因在于check模式下&#xff0c;子元素的勾选状态跟父节…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...