【第1天】每天一个MySQL知识点,百日打怪升级

简介: 本系列以“每天一个知识点”形式,系统讲解MySQL核心原理。首日聚焦Client/Server通信流程,详解三层架构(连接层→SQL层→存储引擎层)、连接管理、查询解析优化及执行计划,直击面试高频考点,助你从CRUD进阶到懂原理、能排障。(239字)

MySQL架构详解:Client/Server通信流程


大家好,我是一名拥有10年以上经验的DBA老兵。

做这个系列,源于一个朴素的愿望:把踩过的坑、总结的经验系统化输出,希望能帮到刚入行或想进阶的兄弟们。

让我们开始今天的第1天内容。


背景引入

💡 说白了:很多同学CRUD写得很溜,但被问到"MySQL是怎么处理你的SQL的"时,一问三不知。

你有没有想过这个问题:

当你执行 SELECT * FROM user WHERE id = 1 这条SQL时,MySQL 内部到底发生了什么?

不了解 MySQL 的架构,就像开车不知道发动机原理——也能开,但出了问题就抓瞎。

今天的目标:搞清楚 MySQL 的"流水线"是怎么工作的,面试必问!


核心概念

MySQL 整体架构

MySQL 是典型的 Client/Server 架构。说白了,就是客户端发请求,服务端处理返回结果。

整体流程就像工厂流水线:

客户端 ──SQL语句──▶ MySQL服务器 ──处理──▶ 返回结果
                         │
                         ▼
                   ┌─────────────┐
                   │  连接层      │  👉 TCP连接、线程管理
                   └─────────────┘
                         │
                         ▼
                   ┌─────────────┐
                   │  SQL层      │  👉 解析→优化→执行
                   └─────────────┘
                         │
                         ▼
                   ┌─────────────┐
                   │ 存储引擎层    │  👉 数据读写、事务支持
                   └─────────────┘

第一关:连接层(Connection Layer)

客户端怎么和 MySQL 建立联系?三次握手 + 创建线程

-- 查看当前连接数及执行结果
> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 15    |
+-------------------+-------+

-- 查看最大连接数及执行结果
> SHOW GLOBAL VARIABLES LIKE 'max_connections';
+-----------------+--------+
| Variable_name   | Value  |
+-----------------+--------+
| max_connections | 1000   |
+-----------------+--------+

面试必问

  • max_connections 最大连接数,默认151,不够用怎么办?
  • wait_timeout 连接空闲超时,默认8小时,太长有啥问题?
  • 为什么 MySQL 早期是每个连接一个线程?现在有什么变化?

💡 MySQL 像餐厅,每个客人(连接)来都分配一个服务员(线程),服务员要一直等着,吃完饭才走。客人太多,服务员忙不过来,就崩了。


📝 面试解答

Q1: max_connections 不够用怎么办?

方案一:适当调大 max_connections(但每个连接都占内存,调太大可能 OOM)
方案二(推荐):使用连接池(HikariCP、Druid),复用连接,别频繁创建新连接
方案三:排查连接泄漏(某些连接没及时 close,一直处于 Sleep 状态)

Q2: wait_timeout 太长有啥问题?

空闲连接占着茅坑不拉屎,浪费资源
攻击者利用这点建立大量空闲连接搞垮 MySQL
推荐设置:30分钟(1800秒)以内

Q3: 为什么 MySQL 早期是每个连接一个线程?现在有什么变化?

早期 MySQL 采用 one-thread-per-connection 模型,实现简单、隔离性好。但在高并发下,大量线程会导致上下文切换开销大、内存消耗高(每个线程默认栈约 256KB,外加会话缓冲区),容易 OOM。

现在的变化

  • 社区版 MySQL(8.0 及以前)依然使用 one-thread-per-connection,没有变化。
  • 企业版从 5.5 开始提供 Thread Pool 插件,让多个连接复用少量工作线程,减少切换开销和内存占用。
  • MariaDB 和 Percona Server 原生支持线程池。

需注意:线程池是服务端线程复用,不是连接复用。客户端仍然推荐使用连接池(如 HikariCP)来减少连接建立成本。


第二关:SQL层(SQL Layer)

SQL 语句进来后,要经过"三道工序":

工序 名字 干啥的
第一道 解析器(Parser) 词法分析、语法检查,确认SQL有没有拼错
第二道 预处理器(Preprocessor) 语义检查,表/列存不存在,有没有权限
第三道 优化器(Optimizer) 生成执行计划,选定用哪个索引
-- EXPLAIN 查看执行计划及执行结果
EXPLAIN SELECT * FROM user WHERE id = 1;

面试考点:优化器怎么选索引?为什么有时候明明有索引却不走?


📝 面试解答

Q: 优化器怎么选索引?为什么有时候明明有索引却不走?

优化器靠统计信息(cardinality)来估算哪个索引划算
不走索引的常见原因:

  1. 统计信息过期——ANALYZE TABLE 刷新一下统计信息
  2. 索引选择性低——比如性别字段加索引,全表扫描更快
  3. 隐式类型转换——WHERE name = 123,name 是 varchar 但给了 int
  4. 回表成本高——优化器估算回表代价太大,不如直接全表扫描划算
    后续会详细讲 EXPLAIN 各个字段的含义

第三关:存储引擎层(Storage Engine Layer)

MySQL 的特点是插件式存储引擎,想用啥就用啥。

-- 查看支持的存储引擎及执行结果
> SHOW ENGINES;
+------------------+---------+-------------------------------------------------------------------+--------------+------+------------+
| Engine           | Support | Comment                                                           | Transactions | XA   | Savepoints |
+------------------+---------+-------------------------------------------------------------------+--------------+------+------------+
| MEMORY           | YES     | Hash based, stored in memory, useful for temporary tables        | NO           | NO   | NO         |
| InnoDB           | DEFAULT | Supports transactions, row-level locking, and foreign keys       | YES          | YES  | YES        |
| PERFORMANCE_SCHEMA | YES   | Performance Schema                                               | NO           | NO   | NO         |
| MyISAM           | YES     | MyISAM storage engine                                            | NO           | NO   | NO         |
| MRG_MYISAM       | YES     | Collection of identical MyISAM tables                            | NO           | NO   | NO         |
| BLACKHOLE        | YES     | /dev/null storage engine (anything you write to it disappears)   | NO           | NO   | NO         |
| CSV              | YES     | CSV storage engine                                               | NO           | NO   | NO         |
| ARCHIVE          | YES     | Archive storage engine                                           | NO           | NO   | NO         |
+------------------+---------+-------------------------------------------------------------------+--------------+------+------------+


-- 查看表使用的存储引擎及执行结果
> SHOW TABLE STATUS FROM schema_name LIKE 't1'\G
LIKE 't1'\G
*************************** 1. row ***************************
           Name: t1
         Engine: InnoDB
        Version: 10
     Row_format: Dynamic
           Rows: 1841
 Avg_row_length: 863
    Data_length: 1589248
Max_data_length: 0
   Index_length: 81920
      Data_free: 6291456
 Auto_increment: 1866
    Create_time: 2026-01-13 16:53:50
    Update_time: NULL
     Check_time: NULL
      Collation: utf8mb4_general_ci
       Checksum: NULL
 Create_options: row_format=DYNAMIC
        Comment:

💡 说白了:存储引擎就是"仓库管理员",InnoDB 是现在的标配,很久以前的 MyISAM 是老江湖。


实战案例

场景一:连接数打满了怎么办?

-- 查看连接详情及执行结果
SHOW FULL PROCESSLIST;

常见问题:

  • 连接数打满:Too many connections
  • 解决思路:调大 max_connections 或在中间件层使用连接池

场景二:查看 SQL 的执行计划

-- 查看SQL执行计划及执行结果
> EXPLAIN SELECT * FROM user WHERE user_name = 'Tom';
+----+-------------+----------+------------+-------+---------------+-----------+---------+-------+------+----------+-------+
| id | select_type | table    | partitions | type  | possible_keys | key       | key_len | ref   | rows | filtered | Extra |
+----+-------------+----------+------------+-------+---------------+-----------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | user     | NULL       | const | user_name     | user_name | 1023    | const |    1 |   100.00 | NULL  |
+----+-------------+----------+------------+-------+---------------+-----------+---------+-------+------+----------+-------+

这是优化器生成的"作业指导书",面试必考,后续单独写一篇关于执行计划的文章,详细讲。


避坑指南

⚠️ 真实踩过的坑:

  1. 连接不是越多越好

    • 每个连接占用内存,过多连接会导致 OOM
    • 生产环境务必使用连接池(HikariCP、Druid)
  2. 短连接 vs 长连接

    • 高并发场景用连接池,避免频繁建立/断开连接
    • 短连接适合低频场景
  3. wait_timeout 别太长

    • 默认8小时,连接占用不释放
    • 推荐设置 30分钟以内,配置的时候是整数,单位为秒

思考题

🤔 互动时间:

  1. 如果你的 SQL 没有走索引,通过什么参数可以看到?
  2. max_connections 设置 2000 行不行?有什么风险?

总结

🎯 面试考点

  • MySQL 三层架构:连接层 → SQL层 → 存储引擎层
  • 每个连接对应一个线程,线程模型
  • max_connectionswait_timeout 参数调优
  • 优化器基于统计信息选索引,索引失效常见原因
  • EXPLAIN 执行计划是面试必考

下期预告:存储引擎的选择:InnoDB vs MyISAM —— 面试必问!

【合集】每天一个MySQL知识点,百日打怪升级


相关文章
|
2月前
|
人工智能 关系型数据库 MySQL
【第3天】每天一个MySQL知识点,百日打怪升级
本系列由10年经验DBA主理,系统讲解MySQL安装(RPM/二进制/源码)与核心配置,涵盖`my.cnf`优先级、`innodb_buffer_pool_size`调优、连接与日志参数设置、四种生效方式对比,并附生产避坑指南与面试高频考点,助力快速入门与实战进阶。(239字)
250 2
|
3月前
|
存储 人工智能 关系型数据库
【第2天】每天一个MySQL知识点,百日打怪升级
【MySQL第2天】深入解析InnoDB与MyISAM核心差异:事务支持、行锁vs表锁、崩溃恢复、外键及适用场景。10年DBA实战总结,助你避开选型陷阱,面试稳拿分!无脑选InnoDB,除非只读/日志等特殊需求。(239字)
260 3
|
2月前
|
SQL 算法 关系型数据库
【MySQL百日打怪升级第10天】JOIN的底层原理与优化:NLJ、Hash Join 与 Merge Join
本文系统解析MySQL三大JOIN算法:NLJ(含Simple/Index/Block变体)、8.0.18引入的Hash Join(O(N+M)复杂度,专治无索引大表连接),以及面试常考但MySQL原生不支持的Sort-Merge Join,附实战EXPLAIN识别与优化指南。(239字)
290 5
|
SQL 缓存 运维
PostgreSQL 事务号回卷分析
## XID 定义 xid 是个啥东西?xid 就是 PostgreSQL 里面的事务号,每个事物都会分配一个 xid。PostgreSQL 数据中每个元组头部都会保存着 插入 或者 删除 这条元组的事务号,即 xid,然后内核通过这个 xid 进行元组的可见性判断。简单理解,比如有两个事务,xid1=200,xid2=201,那么 xid1 中只能看到 t_xmin 200 的元组。 ```c
|
2月前
|
SQL 人工智能 关系型数据库
【第4天】每天一个MySQL知识点,百日打怪升级
本系列由10年经验DBA精心打造,系统梳理MySQL客户端常用命令:从连接参数(-u/-p/-h/-P/字符集)、快捷指令(\s/\q/\G)、数据库/表操作(SHOW/CREATE/DROP/DESC),到状态监控(PROCESSLIST/STATUS/VARIABLES)与实战排障技巧,兼顾面试考点与生产避坑,助你快速上手、底气十足。
227 2
|
3月前
|
SQL 关系型数据库 MySQL
EXPLAIN 执行计划:一眼看穿你的SQL慢在哪
数据库小学妹带你轻松掌握SQL性能诊断!通过EXPLAIN查看执行计划,精准识别索引失效、全表扫描(ALL)、key为NULL等瓶颈。聚焦type、key、rows等6个关键字段,结合实战案例与避坑指南(如函数滥用、最左前缀破坏),让优化有的放矢。学完即用,告别盲目调优!
|
2月前
|
SQL 关系型数据库 MySQL
【MySQL百日打怪升级第14天】 LIMIT 分页的性能优化:深分页到底慢在哪?
本文深入剖析MySQL深分页(如`LIMIT 100000,20`)性能瓶颈:本质是OFFSET导致全量扫描与丢弃,页码越深,扫描行数线性增长。详解三种实战优化方案——游标分页(高效稳定,需有序唯一字段)、延迟关联(兼容OFFSET,索引覆盖减回表)、范围分页(极简但场景受限),并附EXPLAIN对比与避坑指南。(239字)
269 6
|
2月前
|
SQL 算法 关系型数据库
【MySQL百日打怪升级第13天】ORDER BY 的实现原理:面试官最爱问的排序优化
本文详解MySQL中ORDER BY的两种实现原理:索引排序(免排序,高效)与filesort(内存/磁盘排序),剖析单路/双路算法差异,结合EXPLAIN与optimizer_trace实战诊断,并给出索引设计、sort_buffer调优及深分页避坑指南——直击面试高频考点。(239字)
193 4
|
2月前
|
人工智能 关系型数据库 MySQL
【第6天】每天一个MySQL知识点,百日打怪升级
本文为DBA老兵总结的索引优化实战指南:聚焦“何时建、何时不建”核心问题。详解索引选择性(唯一值/总行数)、失效场景(低区分度、函数运算、隐式转换)及建索引黄金法则——WHERE/JOIN/ORDER BY/GROUP BY高频字段优先,状态类、低选择性列坚决不建。附EXPLAIN实战分析与AI辅助诊断技巧。(239字)
237 1