玩转MySQL:如何正确应用索引

MySQL索引探秘:解析索引类型及其应用 索引是数据库中的一种数据结构,用于提高数据检索的效率。它类似于书籍的目录,可以快速定位到需要的数据。 阅读详情

引言

数据库索引,绝对是MySQL的核心功能之一,如果没有索引机制的数据库,那数据的检索效率绝对是令人无法接受的,毕竟没有索引的表数据,就如同一个普通的文本文件存储在磁盘中。在《索引上篇》中,我们对于MySQL提供的索引机制,从引入,到创建、使用、分类、管理....等进行了全面阐述,相信经过上一篇的讲解后,大家对MySQL索引机制建立了系统化的认知,而本篇则会以上篇为基础,对索引机制进一步加深掌握。

不过在上篇中虽对数据库索引机制有了完善认知,但还不够,因为上篇仅是单纯的认知阶段,能否真正的在实际项目中运用好索引机制,还需要具备丰富的经验以及一些原则与方法论,比如下述一些关于索引的问题:

  • 索引虽然能给MySQL检索数据的效率带来质的飞跃,但加入索引没有带来新问题吗?

  • 既然索引能够提升查询性能,那是不是为表中每个字段建立索引,性能会更好?

  • 一张数据表中,哪些类型的字段不适合建立索引呢?又是因为什么原因呢?

  • 表中会存在大量的字段,但其中哪些字段建立索引才能够最大的性能收益呢?

  • MySQL提供的索引种类也不少,一个字段上建立什么类型的索引才最好呢?

  • 当表中存在多个索引时,一条查询SQL有多条路径可走,此时走哪条索引最好?

  • .......

对于这些问题,如果仅靠上篇索引的知识,相信是很难回答具体的,那在本篇中,则重点讲解索引应用相关的方式方法,例如各索引优劣分析、建立索引的原则、使用索引的指南以及索引失效与索引优化等内容。

一、MySQL各索引的优劣分析

首先来聊聊索引机制带来的利害关系,有句古话曾说过:“凡事有利必有弊”,而MySQL的索引机制也不例外,引入索引机制后,能够给数据库带来的优势很明显:

  • ①整个数据库中,数据表的查询速度直线提升,数据量越大时效果越明显。

  • ②通过创建唯一索引,可以确保数据表中的数据唯一性,无需额外建立唯一约束。

  • ③在使用分组和排序时,同样可以显著减少SQL查询的分组和排序的时间。

  • ④连表查询时,基于主外键字段上建立索引,可以带来十分明显的性能提升。

  • ⑤索引默认是B+Tree有序结构,基于索引字段做范围查询时,效率会明显提高。

  • ⑥从MySQL整体架构而言,减少了查询SQL的执行时间,提高了数据库整体吞吐量。

看着上面一条又一条的好处,似乎感觉索引好处很大啊,对于这点确实毋庸置疑,但只有好处吗?No,同时也会带来一系列弊端,如:

  • ①建立索引会生成本地磁盘文件,需要额外的空间存储索引数据,磁盘占用率会变高。

  • ②写入数据时,需要额外维护索引结构,增、删、改数据时,都需要额外操作索引。

  • ③写入数据时维护索引需要额外的时间开销,执行写SQL时效率会降低,性能会下降。

当然,但对数据库整体来说,索引带来的优势会大于劣势。不过也正由于索引存在弊端,因此索引不是越多越好,合理建立索引才是最佳选择。

之前聊过,MySQL的索引也会分为多种类型,每个类型的索引多多少少都存在一些弊端,接下来聊聊其他类型的索引。

1.1、主键索引存在的陷阱

相信大家数据库的表中,主键一般都是使用自增ID,但这是为什么呢?有人可能会回答自增ID不会重复,确保了主键唯一性。这样也确实没错,但不会重复的又不仅仅只有自增ID,比如我使用随机的UUID也不会重复,为何不使用UUID呢?这是由于索引存在一个陷阱!

众所周知,一张表中大多数情况下,会将主键索引以聚簇的形式存在磁盘中,上篇文章也聊到过,聚簇索引在存储数据时,表数据和索引数据是一起存放的。同时,MySQL默认的索引结构是B+Tree,也就代表着索引节点的数据是有序的。

此时结合上面给出的一些信息,主键索引是聚簇索引,表数据和索引数据在一块、索引结构是有序的,那再反推前面给出的疑惑,为何不使用UUID呢?因为UUID是无序的,如果使用UUID作为主键,那么每当插入一条新数据,都有可能破坏原本的树结构,如下:

​比如上图中的灰色节点,是一条新插入的数据,此时经过计算后,应该排第二个位置,那就代表着后面的三个节点需要移动,然后给灰色节点挪出一个位置存储,从而确保索引的有序性。

这里只是伪逻辑,目的是用于举例演示,实际上B+树索引结构不长这样,在《索引原理篇》会重新说一下这个点的。

由于主键索引是聚簇索引,因此上述案例中,当后续节点需要挪动时,也就代表着还需要挪动表数据,如果是偶尔需要移动还行,但如果主键字段值无序,那代表着几乎每次插入都有可能导致树结构要调整。

但使用自增ID就不会有这个问题,所有新插入的数据都会放到最后。

因此大家数据表的主键,最好选用带顺序性的值,否则有可能掉入主键索引的“陷阱”中。

1.2、联合索引存在的矛盾

为了多条件查询时的效率更高,一般都会同时对多个字段建立联合索引,但之前也聊到过,联合索引存在一个致命的问题,比如在用户表中,通过id、name、age三个字段建立一个联合索引,此时来了一条查询SQL,如下:

SELECT * FROM `zz_user` WHERE name = "竹子" AND age = "18"; 复制代码

而这条SQL语句是无法使用联合索引的,为什么呢?因为查询条件中,未包含联合索引的第一个字段,想要使用联合索引,那么查询条件中必须包含索引的第一个字段,如下:

SELECT * FROM `zz_user` WHERE name = "竹子" AND id = 6; 复制代码

上面这条SQL才是能命中多列索引的语句,因此在建立索引时也需要考虑这个问题,确保建立出的联合索引能够命中率够高。

1.3、前缀索引存在的弊端

前缀索引的特点是短小精悍,我们可以利用一个字段的前N个字符创建索引,以这种形式创建的索引也被称之为前缀索引,相较于使用一个完整字段创建索引,前缀索引能够更加节省存储空间,当数据越多时,带来的优势越明显。

不过前缀索引虽然带来了节省空间的好处,但也正由于其索引节点中,未存储一个字段的完整值,所以MySQL也无法通过前缀索引来完成ORDER BY、GROUP BY等分组排序工作,同时也无法完成覆盖扫描等操作。

1.4、全文索引存在的硬伤

之前做模糊查询时,通常都会使用like%语法,不过这种方式虽然能够实现效果,但随着表越来越大,数据越来越多时,其性能会出现明显下降,而全文索引的推出则能够完美解决该问题,可以利用全文索引代替like%语法实现模糊查询,它的性能会比like%快上N倍。

全文索引虽然可以实现模糊查询,但也存在一系列硬伤,一起来看看。

①由于全文索引是基于分词实现的,所以对一个字段建立全文索引后,MySQL会对该字段做分词处理,这些分词结果也会被存储在全文索引中,因此全文索引的文件会额外的大!

②由于全文索引对每个字段值都会做分词,因此当修改字段值后,分词是需要时间的,所以修改字段数据后不会立马自动更新全文索引,此时需要咱们写存储过程,并调用它手动更新全文索引中的数据。

③除开上述两点外,全文索引最大的硬伤在于对中文支持不够友好,类似于英文可以直接通过符号、空格来分词,但中文呢?一个词语来形容就是博大精深,无法精准的对一段文字做分词,因此全文索引在检索中文时,存在些许精准度问题。

因此如果你项目规模较大,通常再引入ElasticSearch、Solr、MeiliSearch等搜索引擎是一个更佳的选择。

1.5、唯一索引存在的快慢问题

唯一索引有个很大的好处,就是查询数据时会比普通索引效率更高,因为基于普通索引的字段查询数据,例如:

SELECT * FROM TABLE_XX WHERE COLUMN_XX = "XX"; 复制代码

假设COLUMN_XX字段上建立了一个普通索引,此时基于这个字段查询数据时,当查询到一条COLUMN_XX = "XX"的数据后,此时会继续走完整个索引树,因为可能会存在多条字段值相同的数据。

但如果COLUMN_XX字段上建立的是唯一索引,当找到一条数据后就会立马停下检索,因此本身建立唯一索引的字段值就具备唯一性。

因此唯一索引查询数据时,会比普通索引快上一截,但插入数据时就不同了,因为要确保数据不重复,所以插入前会检查一遍表中是否存在相同的数据。但普通索引则不需要考虑这个问题,因此普通索引的数据插入会快一些。

1.6、哈希索引的致命问题

哈希索引,也就是数据结构为Hash类型的索引,不过估计大家接触的比较少,毕竟创建索引时都默认用的B+树结构。但要比起查询速度,哈希索引绝对是MySQL中当之无愧的魁首!因为采用哈希结构的索引,会以哈希表的形式存储索引字段值,当基于该字段查询数据时,只需要经过一次哈希计算就可获取到数据。

但哈希结构的致命问题在于无序,也就是无法基于哈希索引的字段做排序、分组等工作。

因此如果你确定一个表中,不会做排序这类的工作,那可以适当选用哈

玩转Mysql 五(MySQL索引) 路虽远行则将至,事虽难做则必成! 滴水穿石,聚沙成塔! 感谢优快云各位大佬的经典博文,在迷茫时能够拨云见日,指点迷津,让我继续一路前行! 如有侵权,请留言,我及时删除! 阅读详情

相关推荐

玩转Mysql 七 (索引的创建与设计原则)

路虽远行则将至,事虽难做则必成! 滴水穿石,聚沙成塔! 感谢优快云各位大佬的经典博文,在迷茫时能够拨云见日,指点迷津,让我继续一路前行! 如有侵权,请留言,我及时删除

weixin_41633010的博客 1469

MySQL使用索引的正确方式你知道吗?

MySQL合理使用索引 索引可以说是数据库中的一个大心脏了,如果说一个数据库少了索引,那么数据库本身存在的意义就不大了,和普通的文件没什么两样。所以说一个好的索引对数据库系统尤其重要,今天来说说MySQL索引中B+树索引好从细节和实际业务的角度看看在MySQL处,以及我们在使用索引时需要注意的知识点。 一、合理利用索引 在工作中,我们可能判断数据表中的一个字段是不是需要加索引的最直接办法就是:这个字段会不会经常出现在我们的where条件中。从宏观的角度来说,这样思考没有问题,但是从长远的角度来看,有时

JAVA88866的博客 1615

MySQL性能优化(四):如何高效正确的使用索引

前期回顾: MySQL性能优化(一):MySQL架构与核心问题 MySQL性能优化(二):选择优化的数据类型 MySQL性能优化(三):深入理解索引的这点事 正确地创建和使用索引是实现高性能查询的基础。前面文章MySQL性能优化(三):深入理解索引的这点事已经介绍了各种类型的索引及其特点,而在实际使用索引中,如何真正有效地发挥索引的价值,还需要进一步持续不断第学习、磨练。接下来本篇文章将分享如何...

xcbeyond|疯狂源自梦想,技术成就辉煌 4030

告别Overleaf!本地LaTeX环境配置:VSCode+TeXLive完全指南(Windows/Mac双平台)

本文详细介绍了如何在Windows和Mac平台上配置本地LaTeX环境,使用VSCode和TeXLive打造高效的专业写作工作流。从TeXLive安装到VSCode插件配置,再到高级技巧与性能优化,帮助用户摆脱Overleaf限制,实现更快速、更私密的学术写作体验。

3c4x5z6v7b的博客 952

Tinder养号防封攻略来了:最新Tinder养号流程和运营攻略

今天,我就来给大家分享一下Tinder养号的具体操作,以及针对Tinder账号被封的一些常见问题为大家做个答疑。

m0_67768117的博客 2万+

最邻近点对问题(Closest-Pair Problem):二维的分治解法详解

低维时,最邻近点对问题可以利用分治求解。但是网络上相关资料良莠不齐,对于3维甚至难有有价值的参考。最近恰巧梳理了123维最邻近点对问题的相关知识,故在此分享。这是该系列的第二篇,介绍二维情况的分治解法。

Carl_Rabbit的博客 1万+

从手机到自动驾驶:MIPI-CSI2协议演进史与车规级改造要点

本文追溯了MIPI-CSI2协议从智能手机摄像头到自动驾驶核心传感器的演进历程。重点剖析了该协议在车规级改造中面临的严苛挑战,包括物理层稳定性、EMC防护、功能安全与数据可靠性等关键要点,并探讨了其在多传感器融合与高带宽实时传输中的工程实践。

weixin_28318011的博客 306

从FedAvg到实战:手把手教你用PyTorch复现联邦学习经典论文实验(MNIST/CIFAR-10)

本文详细介绍了如何使用PyTorch复现联邦学习经典算法FedAvg在MNIST和CIFAR-10数据集上的实验。从环境搭建、数据非IID划分到模型实现和参数聚合,手把手教你掌握联邦学习的核心技术与实战技巧,帮助开发者和研究人员快速实现隐私保护的分布式机器学习方案。

weixin_29053695的博客 252

PCIe Gen4 Switch芯片PM40028调试踩坑实录:从boot引脚设置到串口无输出的诡异问题

本文记录了PCIe Gen4 Switch芯片PM40028的实战调试过程,重点剖析了从boot引脚配置错误导致串口无输出,到使用逻辑分析仪定位并解决启动问题的完整排障思路。文章深入探讨了芯片启动流程、硬件信号测量方法,并总结了高速硬件调试的核心经验与系统性排查清单,为工程师解决类似PCIe Gen4设备调试难题提供实用指南。

i8j9k0l1的博客 250

【异常】Cursor导入Karpathy指南失败解决方案Failed to import GitHub/GitLab rules: Error executing git: Cloning into

摘要:本文解决了Git克隆单个文件报错的问题,指出git clone只能克隆整个仓库而非单个文件。提供了两种解决方案:1) 推荐手动创建规则文件,在Cursor项目中新建.mdc文件并粘贴Karpathy行为指南完整内容;2) 备选克隆整个仓库获取文件。指南包含编码行为规范,强调简单性、精准修改和明确目标。还说明了如何设置全局规则和即时生效的方法。

奶爸的编程之路,也就一周冷个三天 174

如何选择汽车域控制器MCU?一文看透7大关键维度[特殊字符](含芯片推荐、踩坑预警)

MCU选型 Checklist(实用表格)维度你需要考虑的问题Flash/RAM我的任务栈够吗?是否支持OTA双Bank?安全等级这功能出故障会不会危及人命?接口资源够几个CAN?支持CAN FD?ETH是否支持TSN?主频我的软件响应周期是多少?是否带Cache?多核架构是SMP/AMP?是否带锁步核?跑多个任务会不会互相干扰?功耗与封装睡眠电流够低?有外扩DDR空间?BGA能焊?供应链有无国产替代?交期是否稳定?支持AUTOSAR吗?

weixin_43199439的博客 661

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

上一篇: 2022最新大厂面试题整合,阿里、华为、美团等高工手打Java面试宝典(全彩图文版)全网首次公开
下一篇: 玩转MySQL:深入底层理解索引原理
Java_LingFeng
博客等级 码龄4年 505粉丝 259原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值