news 2026/9/3 9:22:11

mysql核心知识清单

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
mysql核心知识清单

目录

索引

数据结构

联合索引

回表

如何处理慢sql

会走哪个索引?

事务

什么是事务

如何实现事务

事务的隔离级别

主从、集群

主从

集群

分库分表

什么时候分库分表

如何分库分表

分库分表技术

分库分表带来的问题


索引

数据结构

B+树,将一条链路的数据挂在叶子节点上的B树:

联合索引

先按照第一个索引排序,第一个索引的值相同时,按照第二个索引排序,以此类推。

回表

innodb中的索引结构都是B+树,但是既有聚集索引,也有非聚集索引。

聚集索引:

B+树的叶子节点上挂的是数据。主键索引是聚集索引,如果没有主键索引,会默认给每个数据行维护一个RowId,用这个RowId来建立一个聚集索引。

innodb从诞生之初,即遵循“索引即数据,数据即索引”的概念,所以,聚集索引的叶子节点,每一个都记录着对应的完整的数据行的内容。

非聚集索引:

B+树的叶子节点上挂的是对应的聚集索引的值。普通索引是非聚集索引。

回表:

通过非聚集索引(主键索引之外的普通索引)来查询时,会先走非聚集索引的B+树,拿到聚集索引的索引值,再去聚集索引的B+树查询对应数据。存在查两个B+树的情况,额外多一轮磁盘IO。

回表明显是基于空间和时间取平衡的一个做法,如果每个索引的树都用聚集索引,可能占的空间会很大,所以牺牲一点时间性能换回了一点空间。

索引下推:

MySQL5.6版本开始,非聚集索引断裂、走不下去后,不会立即回表,还会向下推一步再继续比较其它索引字段,从而减少无意义的额外IO。

如何处理慢sql

定位:

MySQL自身配置中支持开启慢sql监控,常用的数据源也支持开启慢sql的监控,先通过监控把慢sql抓出来。

分析:

通过explain来分析执行计划来分析慢sql,主要看几个关键字段用EXPLAINtype(别全表扫)、看key(走了哪个索引)、看rows(扫了多少行)、看Extra(有没有Using filesort/temporary

优化:

如果分析出来是索引的问题就建索引,如果不是索引的问题,有可能是表里面存的数据不适合存在关系型数据库中,如大json,这时候需要评估是不是要拆数据。

会走哪个索引?

如果一个字段存在于两个索引中,会由索引选择器去选择索引效率高的那个。

事务

什么是事务

在实际工程中发现,数据库要实现ACID,才能满足各种场景需求,也就是原子性、一致性、隔离性、持久性。

持久性通过将数据存在磁盘中来实现,原子性、一致性、隔离性,说白了就是:要保证数据库中数据的版本不能出现中间状态,对数据库的一次“原子操作”,要么全部成功,要么全部失败,就能实现数据库数据版本的干净。所以引入了事务的概念。

事务:一组sql操作要么全部成功,要么全部失败。

讲道理来说,实现事务之间强制的隔离,保证并发的绝对安全就可以了,只是多数数据库在实现的时候发现很多场景要不了太高的隔离度,并且隔离度和吞吐量之间是永远呈反比的关系,为了让开发者自动去取舍吞吐量和隔离度,于是引入了隔离级别,允许手动去控制隔离的度。

mysql事务和存储引擎直接相关,只有innodb支持事务。所以所有事务的讨论都是基于表是innodb引擎的。

如何实现事务

为了保证并发时候的吞吐量,所以mysql实现事务的时候没有直接用锁,而是用了MVCC。

mysql会为innodb中的数据行维护一个隐藏的DB_TRX_ID字段,记录操作这条数据的事务的ID。

每一个未提交事务都会维护一个ReadView,每一个未提交事务单独是一个ReadView,ReadView+undolog来实现MVCC。

ReadView里面会记录:

  • min_trx_id,活跃的最小事务ID,所谓活跃事务就是未提交的事务,innodb会有个数据结构来维护事务ID的集合的,里面会标记哪些事务是活跃事务,去这个里面拿活跃的最小事务的ID即可。

  • max_trx_id,未开始事务ID,也就是去innodb维护的那个事务ID的集合里面拿最大的,然后+1。

  • creator_trx_id,当前事务ID

因为ReadView里面维护了以上几个事务ID,所以去undolog中读数据的时候,就能配合隔级别知道哪些数据是能读的。

事务的隔离级别

并发场景下,数据库会有三种问题:

  • 脏读,一个事务读到另一个未提交的事务的数据。

  • 不可重复读,同一个事务前后读同一个数据,读到的值不一样。和脏读不一样,引起不可重复读问题的原因是在两次读之间另一个提交的事务修改了数据。

  • 幻读,同一事务前后查到的符合条件的结果集不同。比如查age>20,,第一次查到的是10条,间隙另一事务提交新增一条符合的数据,第二次查到11条。和脏读不一样,脏读是具体某个数据,幻读是查符合条件的数据集。

MySQL的innodb提供了几种隔离级别来应对以上情况:

  • 读未提交

  • 读已提交,预防脏读,每次select都会生成一个新的ReadView,所以会存在不可重复读的问题。

  • 可重复读,预防不可重复读,不管select多少次,只生成一个ReadView,可以预防不可重复读的问题。

  • 串行化,预防幻读,这种就不是MVCC了,而是读(select)的时候直接加锁。

主从、集群

主从

主从只是逻辑上的主从,手动去限制主能读能写,从只读不写。主节点、从节点,默认都是可读可写的,除非开启配置SET GLOBAL read_only = ON;

痛点:

  • 读写请求的分发需要手动去控制

  • 主节点挂了后,数据就没办法在节点间自动同步了

集群

mysql8开始引入了InnoDB Cluster这一个自带的原生的mysql集群方案,解决了原生主从集群的两个痛点:

  • 可以自动分发请求

  • 基于Paxos协议,没有主节点的概念,数据是否写入,由节点之间相互投票决定。

分库分表

什么时候分库分表

分库分表会提升系统复杂性,所以要当SQL优化、索引优化、读写分离这些手段都失效后,再考虑分库分表。

如何分库分表

  • 水平分:将一个表分成多份,比如将order分成多个子order,不同子order存储不同数据段。

  • 垂直分:将一个库里的分开到多个库中来存储。

分库分表技术

阿里巴巴开源了分库分表的组件Apache ShardingSphere,其包含三种分库分表的技术,三种任意一种都能实现,根据实际情况来选:

  • Sharding-JDBC,直接托管JDBC,在配置文件中配置数据的分片逻辑。

  • Sharding-Proxy,是个独立的组件服务,对数据库的操作会先走到这个服务上,由这个服务来进行数据的分发。

  • Sharding-Sidecar。

Sharding-JDBC和Sharding-JDBC的区别:

Sharding-JDBC是直接在原服务上接管JDBC且对JAVA友好,对其他语言不友好。

Sharding-Proxy是个单独的服务,JDBC要通过网络先走到这个服务上来,多以耗时要多一些,但是对多语言是友好的。

分库分表带来的问题

在不用任何组件的情况下,原生的分库分表会存在:

跨节点查询失效问题。

如果数据在不同节点上,join、sum、avg等都不好做。

Apache ShardingSphere虽然解决了这个问题,但是会引发新的问题:

要维护很多元数据,这些元数据需要常驻内存,以便进行SQL解析和路由。海量表会消耗大量JVM内存,增加GC压力,甚至导致OOM。

还有就是分布式事务需要单独去处理。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/31 2:15:35

贾子(Kucius)思想纲领 |The Program of Kucius Thought

贾子(Kucius)思想纲领不读贾子(Kucius),不知宇宙之浩瀚;不悟贾子,不知本质之极简;不明贾子,不知规律之森严;不循贾子,不知真理之边界;…

作者头像 李华
网站建设 2026/9/3 9:22:10

吃透 Nginx 核心知识点:从静态部署到反向代理与负载均衡

在 Web 服务架构中,Nginx 早已成为不可或缺的核心组件,这款由俄罗斯程序员开发的轻量级服务器,凭借高性能、高并发、低资源消耗的特性,成为了静态服务部署、反向代理、负载均衡的首选方案。它能轻松支撑 5 万并发连接,…

作者头像 李华
网站建设 2026/9/3 9:21:52

Mask2Former图像分割全攻略:从Swin架构到COCO实战应用 [特殊字符]

Mask2Former图像分割全攻略:从Swin架构到COCO实战应用 🚀图像分割作为计算机视觉的核心任务之一,长期以来一直是学术界和工业界关注的焦点。从传统的像素级分类到现代的深度学习方法,图像分割技术不断演进,为自动驾驶、…

作者头像 李华