MySQL 索引设计的原则

ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花

MySQL索引是提升查询效率的核心手段,合理的索引设计能避免全表扫描、减少IO开销,而不合理的索引不仅无法优化性能,还会增加数据写入(插入、更新、删除)的成本,占用额外存储空间。设计索引需遵循“高效、实用、精简”的核心思路,具体原则如下:

一、优先为高频查询字段建立索引

索引的核心价值是加速查询,因此需优先为查询频率高、过滤性强的字段建立索引。比如用户表的user_id(主键,高频用于查询单个用户)、订单表的order_no(唯一索引,高频用于查询订单详情)、商品表的category_id(高频用于按分类筛选商品)。

反例:为低频查询的字段(如用户表的last_login_ip,仅偶尔统计时使用)建立索引,会浪费存储空间,且增加写入时的索引维护成本。

二、遵循“最左前缀原则”设计联合索引

当查询条件包含多个字段时,优先使用联合索引而非多个单列索引(联合索引可减少索引数量,降低维护成本),且需遵循“最左前缀原则”——联合索引的生效顺序由左至右,查询时需从最左侧字段开始匹配,否则索引会失效。

示例:若建立联合索引(a, b, c),则查询条件包含aa AND ba AND b AND c时索引生效;仅包含bcb AND c时,索引不生效。

注意:联合索引的字段顺序需结合查询场景,将过滤性最强、查询频率最高的字段放在最左侧(比如查询频繁为WHERE a=? AND b=?,且a的区分度更高,则a放左侧)。

三、避免过度索引

索引并非越多越好,每增加一个索引,MySQL在执行插入、更新、删除操作时,都需要同步更新对应的索引结构,会显著降低写入性能;同时,过多的索引会占用大量存储空间,还可能导致MySQL优化器选择错误的索引(索引过多时,优化器判断成本升高)。

建议:单张表的索引数量控制在5-8个以内,删除无用、冗余的索引(如与联合索引最左前缀重复的单列索引,若有联合索引(a, b),则单列索引a属于冗余索引)。

四、选择区分度高的字段作为索引

字段的区分度( cardinality )指字段中不同值的数量占比,区分度越高,索引的过滤效果越好,能快速定位到目标数据,减少扫描行数。

示例:用户表的user_id(唯一值,区分度100%)适合建立索引;而gender(仅男、女、未知三个值,区分度极低)不适合建立索引——即使建立索引,MySQL也可能选择全表扫描(因为过滤后的数据量依然很大,索引查询的开销高于全表扫描)。

注意:区分度的判断可通过SELECT COUNT(DISTINCT 字段名) / COUNT(*) FROM 表名计算,比值越接近1,区分度越高。

五、避免对索引字段进行函数/表达式操作

若查询条件中对索引字段进行函数、表达式或类型转换操作,会导致MySQL无法使用该索引(索引失效),进而触发全表扫描。

反例:SELECT * FROM user WHERE SUBSTR(username, 1, 3) = 'abc'(对索引字段username使用SUBSTR函数)、SELECT * FROM order WHERE create_time + INTERVAL 7 DAY > NOW()(对索引字段create_time进行表达式操作)。

正例:将函数操作转移到查询值上,如SELECT * FROM user WHERE username LIKE 'abc%'(模糊查询前缀匹配,索引生效)、SELECT * FROM order WHERE create_time > NOW() - INTERVAL 7 DAY

六、优先使用覆盖索引,减少回表

覆盖索引是指索引中包含了查询所需的所有字段(即“查询字段 ≤ 索引字段”),此时MySQL无需通过索引定位到数据行后再去读取数据表(回表操作),直接从索引中即可获取所有所需数据,大幅提升查询效率。

示例:若建立索引(id, username, phone),查询SELECT id, username FROM user WHERE id > 100时,无需回表,直接从索引中读取数据。

建议:结合高频查询的字段,设计包含查询所需字段的联合索引,避免“select *”(会导致无法使用覆盖索引,必须回表)。

七、考虑索引的维护成本,适配业务场景

索引的维护成本与数据写入频率正相关:写入频繁(如订单表、日志表)的表,应尽量减少索引数量(避免每次写入都同步更新多个索引);读取频繁、写入较少(如商品表、字典表)的表,可适当增加索引,提升查询效率。

此外,对于大数据量的表,避免建立过长的索引(如 varchar(255) 字段),可通过截取字段前缀建立索引(如INDEX idx_name (name(10))),平衡索引效率和存储空间(前缀长度需根据字段区分度调整,避免过短导致区分度不足)。

八、主键索引优先选择自增整数型

MySQL的InnoDB引擎中,主键索引是聚簇索引(数据行与索引结构绑定),选择自增整数型(如INT、BIGINT)作为主键,有两个核心优势:

  • 自增主键能保证新插入的数据行始终追加在索引末尾,避免索引页分裂(若主键为随机值,新数据会插入到索引中间,导致索引页拆分,增加IO开销);
  • 整数型索引的存储空间更小、查询效率更高(相比字符串主键,如UUID,整数型索引的比较和存储更高效)。

反例:使用UUID、随机字符串作为主键,会导致索引碎片化严重,写入和查询性能下降。

九、避免使用NULL值过多的字段建立索引

MySQL的索引不会存储NULL值(或仅存储NULL的标记),若字段中NULL值占比过高(如超过50%),索引的过滤效果会极差,MySQL可能直接放弃使用该索引,转而执行全表扫描。

建议:对于可能存在大量NULL值的字段,可先通过默认值(如空字符串、0)处理NULL值,再考虑是否建立索引。

总结:MySQL索引设计的核心是“平衡查询效率和维护成本”,需结合业务的查询场景、写入频率、数据量,优先保证高频查询的高效性,同时避免过度索引和无效索引,让索引真正成为提升数据库性能的工具。

ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花

MySQL存储引擎与索引 文章被收录于专栏

还在纠结MySQL存储引擎怎么选?选错直接拉垮系统性能!MySQL插件式存储引擎架构适配多元业务:InnoDB(默认)支持事务、行级锁,扛高并发OLTP场景;MyISAM查询快无事务,适配读多写少场景;Memory读写极速但无持久化,适合临时缓存;Archive高压缩归档日志,CSV便捷跨系统交互,NDB支撑分布式集群。本期专栏拆解各引擎核心特性与选型逻辑,教你选对引擎,让数据库性能拉满!

全部评论
如果大家在工作学习中或者面试中遇到不会的问题可以将问题发在评论区,如果是经典的问题,我可以给出对应的文章,欢迎大家讨论
点赞 回复 分享
发布于 03-10 19:12 北京

相关推荐

【开篇】2025:我的技术成长与求职之路时间过得真快,转眼2025年就要翻篇了。站在年尾回顾,感觉这一年被填得满满当当,从年初的埋头苦学,到年末的尘埃落定,每一个节点回想起来都格外清晰。想和大家分享的,不是什么辉煌的成绩,就是一个普通技术人较为真实的一年。一月到三月:打地基开年的重心很明确,就是夯实后端开发的基础。一月,我一边动手做“苍穹外卖”项目来练手,一边啃完了操作系统和计算机网络这两大块硬骨头,还背了大量的Java八股文。现在想想,那段日子虽然单调,但那种“知道自己在进步”的感觉很踏实。三月份,为了应对天梯赛,我开始在洛谷和PTA上疯狂刷题,每天都跟算法死磕。最终以B组铜牌的成绩收尾,不算惊艳,但也是个不错的开始,这段经历让我觉得,面对反复的练习和暂时的瓶颈,坚持本身就是一种解法。三月到六月:从零到一三月的另一个重点是启动我自己的第一个完整项目:Blossom花店。这是一个Java后端项目,从设计到编码,全都自己摸索。四月初完成了第一版并上传到GitHub,之后就是持续地迭代优化。最幸运的是,后来和一位前端同学组队合作,我们一起把这个项目不断完善,并在六月完成了最终的部署上线。让项目真正跑起来的那一刻,成就感是难以言喻的。更没想到的是,这个项目后来还为我们赢得了网页设计大赛的一等奖。这段经历让我深深体会到,动手做一个完整的、能跑的项目,对能力提升的帮助远超单纯的阅读和刷题,而团队协作则能让想法走得更远。七月到九月:拥抱变化七月,我有了第一段在小厂的后端实习。就在同一时间,我的技术探索欲被点燃,开始着手第二个更具挑战的项目:“淬月智能志愿服务平台”。我尝试将当时最新的SpringAI和RAG技术用进去,搭了几个智能体和知识库,还接入了字节的Coze来进一步优化服务体验。那段时间,工作之外的所有精力几乎都扑在项目上。九月份实习结束后,我根据当时的市场观察和个人兴趣,做了一个重要的方向调整:转向测试开发。这段经历让我觉得,技术之路并非一条单行道,保持对新技术的敏感,并敢于根据现实调整航向,同样重要。十月到十二月:厚积薄发下定决心后,我用九月和十月这两个月的时间,集中火力攻关Python自动化测试脚本开发,并系统地补足了测试的基础理论知识。功夫不负有心人,十月底,我拿到了来自上海哈啰的测试开发岗Offer,这是我人生中第一份真正意义上的大厂Offer。在哈啰实习了两个多月后,一个意外的机会降临——我收到了字节跳动的面试邀请。抱着试一试的心态,我开始了准备。那段时间,每天下班后的必修课就是刷SQL、刷算法、整理公司业务文档、复盘面试八股,周末也跟朋友在星巴克狂卷。过程很辛苦,但现在回想,那段辛苦的日子,恰恰是成长最快的时候。十二月底,我成功拿下了字节的Offer。说实话,那一瞬间除了开心,更多的是一种“努力被看见”的释然。【结尾】写在最后回头看这一年,从年初对着电脑敲下第一行项目代码,到年末手机里收到心仪的Offer邮件,每一步都踩得踉跄却扎实。我学到了一个朴素的道理:技能和项目是敲门砖,而持续的学习能力和面对变化时的调整心态,才是能够走得更远的内驱力。2025年教会我的,不是如何赢,而是如何在一场场小型战役中,保持节奏,不断进化。感谢这一年来所有给予我帮助的伙伴和平台。新的旅程即将开始,希望明年此时,能有更多故事与大家分享。共勉。
双非后端失败第N人:太强了 向佬学习
点赞 评论 收藏
分享
说实话,大多数人第一反应是——再改改,再多投几份,再熬一熬。但我想先问一句:你改简历,是在“优化”,还是在“自我感动”?很多人其实已经陷入一个循环:投 20 份 → 没回复 → 改一行措辞 → 再投 30 份 → 还是没回复 → 怀疑自己。问题是,你改的那几句话,很可能根本不是问题的核心。真正可怕的不是被拒绝,而是连被拒绝的资格都没有——连面试官的第一关筛选都没过。我见过太多这样的情况:有人实习做了 3 个月,写成“参与项目开发”,但具体做了什么没人看得出来。有人明明优化过系统性能,却只写“提升效率”,却没量化到具体数据。有人项目做得很复杂,却用一堆术语堆砌,看完不知道价值在哪。还有人简历排版密密麻麻,像论文摘要。这些问题,你自己很难发现。为什么?因为你对自己的经历太熟了。你知道每一句话背后的故事,但面试官不知道。你看到“参与搭建系统”,脑海里是加班、重构、联调;面试官看到的只是一个模糊动词。这就是认知盲区。很多人硬扛,是因为不好意思把简历给别人看。怕被说菜,怕被否定,怕自尊心受伤。但现实是——市场不会顾及你的自尊心。真正有效的办法反而很简单:把简历亮出来。找同行前辈,找已经拿到 offer 的同学,甚至找愿意给建议的面试官朋友。让他们“拷打”你。三分钟扫一遍,他们会直接指出:“这段看不出成果。”“这里逻辑不清晰。”“这个项目没有亮点。”“这和你投的岗位不匹配。”很多问题,你自己可能三个月都发现不了。我曾经也是典型的“硬扛型选手”。连续投简历一个多月没什么反馈,我只是在改措辞,把“负责”改成“主导”,把“参与”改成“深度参与”。直到有一次鼓起勇气把简历发给一个学长,他只花了五分钟,说了一句话:“你写的是做了什么,不是创造了什么。”那一刻我才明白,我的问题不是表达不够华丽,而是结构错了。我开始用一个新的思路改简历——每一段经历必须回答三个问题:你解决了什么问题?你采取了什么行动?结果产生了什么可量化变化?当我按这个逻辑重写后,面试率明显提升。后来我发现,其实很多同学缺的不是能力,而是“外部视角”。有时候我们太沉浸在自我叙事里,看不清市场在看什么。现在有很多工具也能帮你做第一轮“自我拷打”。比如我后来用过泡泡小程序AiCV简历王,它的一个好处是会从岗位匹配度、关键词覆盖、成果量化程度等维度去结构化分析。你会发现,有些岗位 JD 里反复出现的核心词,你的简历里根本没体现;有些经历明明可以量化,却被你写成了泛泛而谈。它不能替代真人前辈的犀利点评,但至少能帮你先把明显漏洞筛出来,避免低级错误。不过,工具只是辅助。真正重要的是心态。别把简历当成“面子工程”。别把修改当成对能力的否定。别把反馈当成攻击。简历是一个产品,而你是产品经理。产品卖不出去,不是靠自尊心支撑的,而是靠不断迭代。有时候你需要的不是“多投 100 份”,而是“被拷打 10 分钟”。我见过一个同学,连续 80 多份简历没有面试。后来在一个群里公开求改,十几个人一起提意见。有人帮他删掉无效经历,有人帮他重构项目逻辑,有人建议他换岗位定位。两周后,他开始陆续收到面试邀请。真正的转折点,不是努力更多,而是视角改变。所以如果你现在还在一个人默默改简历、焦虑、怀疑自己,我真心建议:别硬扛。把简历亮出来。让别人帮你找问题。让市场提前给你反馈。被“拷打”不可怕,被无视才可怕。求职本质上是一个信息博弈。你以为自己表达清楚了,但市场没接收到。你以为自己不够优秀,其实只是表达不匹配。当你愿意让外部视角介入,你会发现,很多所谓的“能力不够”,只是包装方式出了问题。三分钟,可能就能发现你自己永远看不到的盲区。而那三分钟,有时候比你一个月的独自焦虑更有价值。
xx岗简历求拷打
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务