-- 基础查询SELECT id, username, email FROMuserWHERE status =1;
-- 条件查询与排序SELECT*FROMuserWHERE created_at >='2023-01-01'AND status IN (1, 2)
ORDERBY created_at DESC, id ASC LIMIT 10OFFSET0;
-- 聚合查询SELECTCOUNT(*) AS total_count, MAX(id) AS max_id, AVG(id) AS avg_id FROMuser;
第二部分:核心篇 —— 深入理解 MySQL 架构与原理
第三章:MySQL 逻辑架构与存储引擎
3.1 逻辑架构分层
理解架构有助于排查问题。MySQL 大致分为四层:
连接层:处理客户端连接、认证、权限校验。
服务层:负责 SQL 解析、优化、缓存及内置函数。
引擎层:负责数据存储和提取,支持插件式架构。
存储层:管理数据文件和日志文件。
3.2 核心存储引擎对比
InnoDB(默认):支持事务(ACID)、行级锁、外键、聚簇索引和 MVCC。适合高并发写场景。
MyISAM:不支持事务和外键,使用表级锁。读多写少场景适用,现已较少使用。
第四章:索引优化与性能分析
4.1 索引的本质与数据结构
索引是帮助 MySQL 高效获取数据的排好序的数据结构。InnoDB 默认使用 B+Tree。
B+Tree 特性:非叶子节点只存键值,树高度低;叶子节点存数据且形成链表,支持范围查询。
为什么不选二叉树? 极端情况下会退化成链表;B 树数据分散,范围查询需回溯。
4.2 索引类型与使用场景
主键索引:叶子节点存整行数据。
二级索引:叶子节点存主键值,查询可能需回表。
联合索引:遵循最左前缀原则。
全文索引:用于文本搜索。
4.3 索引优化策略与失效场景
最左前缀法则:
-- 假设创建了联合索引 (name, age, city)-- ✅ 有效:命中 name 和 ageSELECT*FROMuserWHERE name ='A'AND age =20;
-- ✅ 有效:命中 nameSELECT*FROMuserWHERE name ='A';
-- ❌ 失效:未使用最左列SELECT*FROMuserWHERE age =20;
-- ❌ 失效:跳过中间列SELECT*FROMuserWHERE name ='A'AND city ='BJ';
-- INNER JOIN: 返回匹配的行SELECT u.name, o.order_no FROMuser u INNERJOIN orders o ON u.id = o.user_id;
-- LEFT JOIN: 返回左表所有行SELECT u.name, o.order_no FROMuser u LEFTJOIN orders o ON u.id = o.user_id;
-- 自连接:查询员工及其上级SELECT e.name, m.name AS manager FROM employee e LEFTJOIN employee m ON e.manager_id = m.id;
6.2 子查询与派生表
-- 标量子查询SELECT name, (SELECTMAX(salary) FROM employee) FROM employee;
-- EXISTS 子查询:通常比 IN 性能更好SELECT*FROMuser u WHEREEXISTS (SELECT1FROM orders o WHERE o.user_id = u.id);
6.3 窗口函数(MySQL 8.0+)
窗口函数在不改变行数的情况下进行聚合,非常适合排名和累积计算。
-- 排名SELECT name, salary, ROW_NUMBER() OVER (ORDERBY salary DESC) AS row_num FROM employee;
-- 分组排名SELECT name, dept_id, salary, RANK() OVER (PARTITIONBY dept_id ORDERBY salary DESC) AS dept_rank FROM employee;
第七章:SQL 优化实战
7.1 海量数据分页优化
传统 LIMIT 1000000, 10 效率极低。可采用延迟关联或书签法。
-- 延迟关联:先定位主键再回表SELECT*FROMuserINNERJOIN (
SELECT id FROMuserORDERBY id LIMIT 1000000, 10
) AS tmp ON user.id = tmp.id;
-- 书签记录法:记住上一页最大 IDSELECT*FROMuserWHERE id >1000000ORDERBY id LIMIT 10;