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

举一个具体例子说明为什么索引不是越多越好,举具体字段

文章目录

    • 1. 核心舞台:笔记表 (`t_note`) 结构设计
      • 🚨 错误的操作:
    • 2. 结合具体字段,拆解三大翻车现场
      • 现场一:给 `view_count`(浏览量)加索引 —— 导致写放大,拖垮数据库
      • 现场二:给 `status`(状态)加索引 —— 优化器直接放弃,索引纯粹沦为累赘
      • 现场三:单独给 `user_id` 和 `create_time` 加索引 —— 遭遇多条件查询时的“ filesort 降维打击”
    • 3. 面试总结话术

为了让你在面试中能把这个概念“讲出画面感”,我们直接以你熟悉的社交平台(如小红书、博客系统)的“笔记表(t_note)”为例。

我们来看一张设计非常典型的表,以及如果“盲目滥建索引”会引发怎样的系统灾难。


1. 核心舞台:笔记表 (t_note) 结构设计

假设我们的数据库里有一张表,包含以下 5 个核心字段:

字段名数据类型字段含义业务读写特征
idBigInt笔记唯一 ID主键(自动拥有聚簇索引)
user_idBigInt作者用户 ID经常用来查询“某用户发布的所有笔记”
statusTinyInt审核状态只有 3 个值:0-草稿,1-审核中,2-已发布
view_countInt笔记浏览量高频变动,用户每点击一次,数值就+1
create_timeDateTime创建时间经常用来做“按最新时间排序”的列表展示

🚨 错误的操作:

一个缺乏经验的开发人员奉行“资源无限,建了再说”的原则,给user_idstatusview_countcreate_time每一个字段都单独建立了一个单列索引


2. 结合具体字段,拆解三大翻车现场

现场一:给view_count(浏览量)加索引 —— 导致写放大,拖垮数据库

view_count是一个高频变动的数值型字段。每当一篇热门笔记被上万人浏览时,后端会疯狂执行:

UPDATEt_noteSETview_count=view_count+1WHEREid=999;
  • 不建索引时:数据库只需要找到id=999的行,把里面的数字直接改掉,极其迅速。
  • 建了idx_view_count索引后:B+ 树索引为了保证“可以通过浏览量快速排序”,它要求树里的数据必须是严格有序的。
    view_count100变成101时,它在原先索引树里的位置就失效了。MySQL 必须做两件事:
  1. 把旧的100从原来的索引节点里抹去
  2. 拿着新的101去索引树里重新寻路,插入到新的正确位置。
  • 灾难后果:如果并发量高,索引树为了容纳频繁变动的数值,会发生频繁的页分裂与节点合并。CPU 算力全部被浪费在“维持这棵树的平衡”上,磁盘 I/O 瞬间飙满,哪怕磁盘无限大,写入通道也会直接被塞死。

说白了,就是因为非聚簇索引和聚簇索引,每个非叶子结点就是索引列的值,如果你经常修改这个索引列,就会导致这个索引列重排序,需要频繁发生页分裂和节点合并,瞬间磁盘IO拉满


现场二:给status(状态)加索引 —— 优化器直接放弃,索引纯粹沦为累赘

status字段的特性是“区分度极低”(基数太小),一共就0, 1, 2三种可能。

假设你的平台有 1000 万条笔记,其中“已发布(status=2)”的笔记占了 900 万条。此时用户在前端刷信息流,触发查询:

SELECT*FROMt_noteWHEREstatus=2;
  • MySQL 优化器的内心独白:“我想查状态为 2 的数据。如果我走idx_status索引,我得在这棵树里找出 900 万个节点,然后拿着这 900 万个主键 ID,再去主键索引树里回表(Lookup)900 万次去拿完整数据……这太傻了,我不如直接把整张表从头到尾扫描一遍(Full Table Scan)来得快!”
  • 灾难后果:最终优化器会直接放弃这个索引,选择全表扫描。这意味着,这个索引在查询时毫无用处;但每次有新笔记发布(Insert)或下架(Update status)时,MySQL 还必须硬着头皮去更新这棵没用的索引树。它变成了纯粹的“带薪摸鱼”累赘。

现场三:单独给user_idcreate_time加索引 —— 遭遇多条件查询时的“ filesort 降维打击”

当我们在个人主页看某个大 V 的笔记时,通常需要:看某个用户的、并且按时间倒序排列的最新笔记。

SELECT*FROMt_noteWHEREuser_id=8888ORDERBYcreate_timeDESC;
  • 现状:我们有独立的idx_user_id和独立的idx_create_time

  • MySQL 的尴尬:在一条查询里,MySQL通常一次只能选择使用一个单列索引

  • 如果它选了idx_user_id,它能快速定位出作者是 8888 的 1 万条笔记。但接下来,为了实现ORDER BY create_time DESC,它不得不把这 1 万条数据拉到内存甚至磁盘里,进行痛苦的filesort(文件排序)

  • 如果它选了idx_create_time,它会丧失筛选作者的能力。

  • 灾难后果:两个独立的索引并没有让“联合查询+排序”变快。

  • 正确解法:应该砍掉这两个独立索引,建立一个**联合索引idx_user_time(user_id, create_time)**。让数据在叶子节点里由于最左匹配原则,天然既按用户分类,又在分类内部按时间排好序,实现真正的O ( 1 ) O(1)O(1)级精准秒出。


3. 面试总结话术

以后被问到这个问题,把这个例子甩给面试官:

“比如在社交平台的笔记表设计中,如果给**‘浏览量(view_count)’这种高频变动字段加索引,会导致每次点击都引发 B+ 树的节点分裂与重排,引发严重的写放大**;
如果给**‘审核状态(status)’这种区分度极低的字段加索引,由于回表成本过高,优化器在查询时会直接弃用**,导致其沦为只耽误写入性能的累赘;
如果在‘按作者查看最新笔记’的场景下,盲目建两个独立的单列索引,依然无法避免大数据量下的filesort内存排序,远不如建一个(user_id, create_time)联合索引有效。
所以,空间哪怕无限,索引也必须精准克制。”

http://www.zskr.cn/news/1384924.html

相关文章:

  • CanTSyn vs PTP:在ADAS域控制器里,我们最终为什么选了它?
  • 告别CAJ格式困扰:3分钟学会用开源工具将知网文献转为PDF
  • 一个取巧但有效的方法:利用PAT报错信息反向“猜”出测试数据(附Python二分脚本)
  • 从“DOC/PDF”到“WPS”:细看GJB438C-2021文档格式要求背后的国产化信号与落地指南
  • OBS多平台直播革命:obs-multi-rtmp插件让你一次推流,全网覆盖
  • 深挖 okbiye 核心能力|AI 毕业论文写作新模式,高效攻克毕业创作难题
  • Redis持久化机制详解
  • 百度文心一言开发者如何通过Taotoken低成本接入多模型API
  • 2026 年 AI 毕业论文工具横评:从降 AIGC 率到智能排版,10 款平台实测谁才是毕业季的 “救命稻草”
  • 2027考研全套资料免费分享
  • DragonBones与Godot集成:骨骼动画的可编程化实践
  • 2026 上海 GEO 优化机构实力榜:AI 搜索第一推荐位抢占攻略 - GEO优化
  • 从游戏引擎到仿真平台:手把手教你用AirSim+UE4搭建你的第一个无人机/自动驾驶仿真环境
  • Python UiAutomation实战:从网页数据抓取到桌面应用,一个库打通数据采集全链路
  • 城通网盘直链获取终极指南:3分钟快速获取高速下载地址
  • CAPL脚本效率翻倍秘诀:巧用testfunction组织你的自动化测试用例
  • UE5项目避坑指南:内存泄漏、打包失败与渲染异常的底层归因
  • 别再无脑用--nogpgcheck了!Linux yum安装PostgreSQL时GPG校验失败的3种安全处理姿势
  • 机器学习在营养流行病学中的应用:基于NHANES数据的癌症风险预测模型构建与评估
  • 数据库范式化设计与性能优化全攻略
  • 原子化半格:从数据中“生长”出可解释规则与泛化模型
  • 在多轮对话应用中观察Taotoken计费对成本的影响
  • 基于Arduino与PID算法DIY高性能SMD焊台:适配Weller RT焊头
  • 1000元到6000元,不同预算买哪款电钢琴?2026年电钢琴选购推荐指南
  • Godot 4.2 保姆级教程:从零到一复刻《Dodge the Creeps!》完整避坑指南
  • 告别论文写作 “地狱模式”!okbiye 毕业论文智能写作,把开题到定稿的坑全填上了
  • Unity中稳定低开销3D描边实现方案
  • 05华夏之光永存:150吨级火星EDL进入下降着陆全链条解决方案
  • OFD转PDF专业解决方案:Ofd2Pdf开源工具全面指南
  • 解密高校教师必会的Gemini 3.1 Pro五大科研隐藏技能:从论文评估到创新点锁定