执行一条SQL的请求过程

-- MySQL 查询执行顺序(数字=执行步骤,括号标注)
(9) SELECT -- 9. 选择最终要返回的字段/表达式
(10) DISTINCT <column>, -- 10. 对SELECT结果去重
(6) AGG_FUNC <column> or <expression>, ... -- 6. 执行聚合函数(SUM/COUNT/AVG等)
(1) FROM <left_table> -- 1. 确定查询的主数据源(左表)
(3) <join_type> JOIN <right_table> -- 3. 根据连接类型(LEFT/RIGHT/INNER)补充主表未匹配行
(2) ON <join_condition> -- 2. 筛选满足表关联条件的行(JOIN的前置过滤)
(4) WHERE <where_condition> -- 4. 过滤行记录(不能用聚合函数)
(5) GROUP BY <group_by_list> -- 5. 按指定字段分组(将行聚合为“组”)
(7) WITH {CUBE | ROLLUP} -- 7. (可选)对分组结果做多维/层级汇总
(8) HAVING <having_condition> -- 8. 过滤分组后的结果(可使用聚合函数)
(11) ORDER BY <order_by_list> -- 11. 对最终结果集排序(可使用聚合字段)
(12) LIMIT <limit_number>; -- 12. (可选)限制返回的行数
example
select *
from tableA
inner join tableB
on tableA.id = tableB.id
left join tableC
on tableA.id = tableC.id
where tableA.status = 'active'
group by tableA.id
having count(tableB.id) > 0
order by tableA.id
limit 10;
- 连接器:建立连接,管理连接、校验用户身份;
- 查询缓存:查询语句如果命中查询缓存则直接返回,否则继续往下执行。MySQL 8.0 已删除该模块;
- 解析SQL,通过解析器对SQL查询语句进行词法分析、语法分析,然后构建语法树,方便后续模块读取表名、字段、语句类型
- 执行SQL
- 预处理:检查表或字段是否存在;将select * 中的*符号扩展为表上的所有列
- 优化阶段:基于查询成本的考虑, 选择查询成本最小的执行计划;
- 执行阶段:根据执行计划执行 SQL 查询语句,从存储引擎读取记录,返回给客户端;
MySQL的引擎
- InnoDB:InnoDB是MySQL的默认存储引擎,具有ACID事物支持,行级锁、外键约束等特性。适用于高并发的读写操作,支持较好的数据完整性金额并发控制
- MyISAM:MyISAM是mySQL另一种常见存储引擎,具有较低的存储空间和内存消耗,适用于大量读的场景。然而,MyISAM不支持事务、行级锁和外键约束,因此在并发写入和数据完整性方面有一定的限制。
- Memory:Memory引擎将数据存储在内存中,适用于对新能要求较高的读场景,但是服务器重启后,数据就会丢失。不支持事物、行锁和外键约束。
InnoDB引擎在事务支持、并发控制、崩溃恢复方面具有优势,因此MySQL选择为默认的存储引擎。
- 事务支持:InnoDB引擎提供对事务的支持,可以进行ACID操作。
- 并发性能:事务采用行级锁的机制,可以提供更好的并发性能。MyISAM是表锁。
- 崩溃恢复:InnoDB引擎通过redolog日志实现崩溃恢复,可以在数据库异常情况下,通过日志进行恢复,保证数据的持久性和一致性。
从数据文件视角看table和database
InnoDB引擎下,我们每创建一个 database(数据库) 都会在 /var/lib/mysql/目录里面创建一个以 database 为名的目录,然后保存表结构和表数据的文件都会存放在这个目录里。
db.opt
t_order.frm
t_order.ibd
| 文件 | 类型 | 核心作用 | 依赖关系 |
|---|---|---|---|
| db.opt | 数据库配置 | 数据库默认字符集 / 排序规则 | 影响表的默认字符集 |
| t_order.frm | 表结构元数据 | 表字段、索引、约束定义 | 无 .frm 则无法识别表结构 |
| t_order.ibd | 数据 / 索引存储 | InnoDB 表的实际数据 + 索引 | 依赖 .frm 定义的表结构 |