本页内容受版权保护 · 已添加水印 · 禁止任何形式转载
SQL 面试题库·中英双语 · 258 题
从执行计划到窗口函数。
索引设计 · MVCC · 间隙锁 · redo/binlog · 主从复制 · 分库分表 · 30+ 道实战 SQL 编程题与字节 / 阿里 / 拼多多 / 滴滴 / 小红书 真题——每题配结构化解题思路。
258题目
258含完整解答
12分类
42子分类
§1
SQL 语言基础(DDL / DML / DCL / TCL)
25 题1.1
DDL — 库与表的创建
- 1CREATE / ALTER / DROP / RENAME / TRUNCATE 各自的语义和区别?FULL
- 2CREATE TABLE 中的 PRIMARY KEY、UNIQUE、NOT NULL、CHECK、DEFAULT、AUTO_INCREMENT 各自含义与使用场景?FULL
- 3DROP、TRUNCATE、DELETE 三者的区别?分别在哪些层面(DDL/DML、事务、自增、空间、触发器)有差异?FULL
- 4ALTER TABLE 添加列时是否会锁表?MySQL 8.0 / 5.7 的在线 DDL 与传统 DDL 区别?FULL
- 5如何把表从 MyISAM 转成 InnoDB?过程会发生什么?需要注意什么?FULL
- 6如果一张大表需要在线添加索引/列,应该如何设计来避免长时间锁表(pt-online-schema-change / gh-ost 等)?FULL
1.2
DML — 数据增删改
- 1INSERT INTO / INSERT INTO ... SELECT / INSERT IGNORE / REPLACE INTO / INSERT ... ON DUPLICATE KEY UPDATE 各自的语义?分别用在什么场景?FULL
- 2UPDATE 时如果同时使用 ORDER BY 和 LIMIT 有什么用?典型场景?FULL
- 3如何高效地删除一张大表中 90% 的数据?为什么不能直接 DELETE?FULL
- 4为什么 DELETE 大量数据后,表文件大小不会变?(redo / undo / 数据页空洞)FULL
- 5MySQL 的 INSERT 性能优化技巧有哪些?(batch、关闭自动提交、关闭索引、关闭唯一性检查、调大 bulk_insert_buffer 等)FULL
- 6什么是 LOAD DATA INFILE?相比 INSERT 有何优势?什么场景使用?FULL
1.3
DCL / TCL — 权限与事务
1.4
数据类型选型
- 1INT / BIGINT / TINYINT / SMALLINT 各占几字节?什么时候用哪个?FULL
- 2DECIMAL 和 FLOAT/DOUBLE 的区别?金融场景为什么必须用 DECIMAL?FULL
- 3CHAR vs VARCHAR vs TEXT vs LONGTEXT:存储方式、长度限制、索引限制?FULL
- 4DATETIME 与 TIMESTAMP 的区别?时区处理?为什么 TIMESTAMP 容易踩坑?FULL
- 5JSON 类型的优劣?什么时候应该用 JSON 列,什么时候应该拆成关系表?FULL
- 6为什么不推荐用 ENUM?哪些场景下 ENUM 仍然合理?FULL
- 7SET 类型与 BIT 类型的使用场景?FULL
- 8如何选择合适的字符集和排序规则(utf8 vs utf8mb4 vs utf8mb4_0900_ai_ci)?FULL
§2
查询基础(SELECT / JOIN / 聚合 / 排序)
29 题2.1
SELECT 与 WHERE
- 1SQL 一条查询语句的执行顺序是怎样的?(FROM → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → LIMIT)FULL
- 2WHERE 与 HAVING 的区别?为什么 HAVING 可以用聚合函数而 WHERE 不行?FULL
- 3IN 与 EXISTS 的区别?什么时候 IN 更快,什么时候 EXISTS 更快?FULL
- 4NULL 在 WHERE 子句中的特殊行为?为什么 col = NULL 不能用,必须用 IS NULL?FULL
- 5BETWEEN ... AND 是闭区间还是开区间?日期边界容易踩坑的地方?FULL
- 6DISTINCT 的实现原理?为什么对大表慎用 DISTINCT?与 GROUP BY 实现差异?FULL
- 7LIMIT offset, count 的性能为什么会随 offset 增大而暴跌?如何用游标式翻页(keyset pagination)优化?FULL
2.2
JOIN 多表连接
- 1INNER JOIN / LEFT JOIN / RIGHT JOIN / FULL JOIN / CROSS JOIN 各自语义?示例区别?FULL
- 2ON 子句和 WHERE 子句对 LEFT JOIN 结果的影响有什么不同?FULL
- 3MySQL 的 NLJ(Nested Loop Join)、BNL(Block Nested Loop)、Hash Join 各自适用场景?8.0 之前为什么没有 Hash Join?FULL
- 4什么是驱动表?如何判断哪个表应该作为驱动表?STRAIGHT_JOIN 的作用?FULL
- 5Self join 的典型场景?(经理-员工、推荐关系链等)FULL
- 6如果两张大表 JOIN 性能很差,可以用哪些手段优化?FULL
- 7什么是笛卡尔积?什么场景需要刻意制造笛卡尔积?(日期补全等)FULL
- 8USING / NATURAL JOIN 与 ON 的区别?为什么大多数生产环境不推荐 NATURAL JOIN?FULL
2.3
聚合与分组
- 1COUNT(*) / COUNT(1) / COUNT(col) 三者性能与语义有什么不同?InnoDB 与 MyISAM 的差异?FULL
- 2GROUP BY 后 SELECT 的列必须出现在 GROUP BY 中或聚合函数内吗?为什么 MySQL 默认(sql_mode=ONLY_FULL_GROUP_BY)严格要求?FULL
- 3ROLLUP 与 CUBE 的作用?多维汇总场景怎么用?FULL
- 4GROUP_CONCAT / STRING_AGG 的功能?默认长度限制 group_concat_max_len 怎么调?FULL
- 5AVG / SUM / MIN / MAX 在面对 NULL 时的行为?FULL
- 6如何统计每天每小时的活跃用户数?(date_format / hour() / 时间分桶)FULL
- 7为什么 SELECT COUNT(DISTINCT col) 在大表上很慢?有哪些近似算法(HyperLogLog 等)?FULL
2.4
ORDER BY 与排序
§3
进阶查询(窗口函数 / CTE / 递归 / 子查询)
19 题3.1
窗口函数(Window Functions)
- 1什么是窗口函数?与 GROUP BY 聚合函数的本质区别?FULL
- 2ROW_NUMBER() / RANK() / DENSE_RANK() 三者有什么区别?分别在什么场景使用?FULL
- 3LAG() 和 LEAD() 的语义?典型应用:求同比/环比?FULL
- 4FIRST_VALUE / LAST_VALUE 的使用?为什么 LAST_VALUE 经常和你期望的不一样(默认窗口为 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)?FULL
- 5PARTITION BY 与 ORDER BY 子句在窗口函数中的作用?FULL
- 6ROWS BETWEEN 与 RANGE BETWEEN 有什么区别?滑动窗口怎么写?FULL
- 7NTILE(n) 的功能?如何用窗口函数把数据分成等大的 n 桶?FULL
- 8如何用窗口函数找出每个分组中第 N 名的记录?(ROW_NUMBER 子查询模式)FULL
- 9如何用窗口函数实现连续登录 N 天的用户检测?(row_number 与日期相减)FULL
3.2
CTE 与递归查询
§4
索引(B+ 树 / 覆盖 / 失效 / 优化)
22 题4.1
索引数据结构
- 1为什么 MySQL InnoDB 使用 B+ 树而不是 B 树、红黑树、跳表、哈希表?FULL
- 2B+ 树相比 B 树的优势是什么?(全部数据在叶子层、相邻叶子有指针、范围查询快、磁盘 I/O 少)FULL
- 3InnoDB 的页(page)大小默认是多少?为什么是 16KB?一棵 3 层 B+ 树能存多少行数据?FULL
- 4聚簇索引(Clustered)和非聚簇索引(Secondary)的区别?InnoDB 与 MyISAM 在这点上有何差异?FULL
- 5什么是回表?为什么二级索引查询通常要回表,覆盖索引能避免?FULL
- 6什么是哈希索引?InnoDB 的自适应哈希索引(Adaptive Hash Index)什么时候触发?FULL
- 7什么是全文索引(FULLTEXT)?InnoDB 5.6+ 才支持,与 MyISAM 的差异?FULL
4.2
索引种类与设计
- 1主键索引、唯一索引、普通索引、联合索引、前缀索引各自语义?FULL
- 2什么是覆盖索引(Covering Index)?如何利用 EXPLAIN 看出覆盖索引生效?FULL
- 3什么是最左前缀原则?联合索引 (a, b, c) 哪些查询能命中?FULL
- 4什么是索引下推(Index Condition Pushdown, ICP)?MySQL 5.6+ 怎么减少回表?FULL
- 5前缀索引的使用场景?长字符串列怎么决定前缀长度?(区分度评估)FULL
- 6何时不应该建索引?(超低基数、写多读少、表本身很小、列经常更新)FULL
- 7联合索引的列顺序如何选择?等值在前、范围在后的原则?FULL
- 8字符串列何时需要转 hash 列加索引?身份证号、URL 等场景?FULL
4.3
索引失效与执行计划
- 1哪些操作会导致索引失效?(隐式类型转换、函数包裹列、!=、NOT IN、模糊查询前置%、OR 部分列无索引等)FULL
- 2EXPLAIN 输出的关键字段(type, key, key_len, rows, Extra)各自含义?FULL
- 3type 列从最优到最差排序?(system > const > eq_ref > ref > range > index > ALL)FULL
- 4Extra 列常见值的含义:Using index、Using where、Using filesort、Using temporary、Using join buffer 等?FULL
- 5如何用 EXPLAIN ANALYZE / SHOW WARNINGS 看真实执行成本?FULL
- 6什么是索引选择性(cardinality)?基数过低的索引为什么没用?FULL
- 7如何使用 FORCE INDEX / IGNORE INDEX / USE INDEX 干预优化器选择?FULL
§5
事务与并发(ACID / 隔离级别 / 锁 / MVCC)
25 题5.1
ACID 与隔离级别
- 1ACID 四大特性各自的含义?数据库通过什么机制分别保证?FULL
- 2并发事务可能产生哪些问题?(脏读、不可重复读、幻读、丢失更新)FULL
- 3SQL 标准的四种隔离级别?各自能解决什么问题?FULL
- 4MySQL InnoDB 的默认隔离级别是 RR,为什么不是 RC?FULL
- 5RR(可重复读)是否解决了幻读?InnoDB 是怎么用 next-key lock 处理幻读的?FULL
- 6如何在会话级别 / 全局设置隔离级别?SET TRANSACTION ISOLATION LEVEL 语法?FULL
- 7什么是快照读和当前读?SELECT 普通查询是哪种?SELECT ... FOR UPDATE / LOCK IN SHARE MODE?FULL
5.2
MVCC 多版本并发控制
5.3
锁机制
- 1InnoDB 的行锁、间隙锁(Gap Lock)、Next-Key Lock 各自作用?FULL
- 2行锁是加在记录上还是索引上?没有索引时会发生什么?FULL
- 3什么是意向锁(Intention Lock)?IS / IX 锁如何避免行锁与表锁冲突?FULL
- 4什么是死锁?InnoDB 如何检测死锁?面试常考的死锁示例?FULL
- 5如何排查死锁?SHOW ENGINE INNODB STATUS 关键信息?FULL
- 6什么是元数据锁(MDL)?为什么 DDL 和 DML 之间会互相阻塞?FULL
- 7悲观锁与乐观锁的区别?分别什么场景使用?(SELECT FOR UPDATE vs version 字段)FULL
- 8什么是表锁、自增锁(AUTO-INC Lock)?innodb_autoinc_lock_mode 三个值的差异?FULL
§6
存储引擎(InnoDB / MyISAM / 其他)
13 题6.1
InnoDB
- 1InnoDB 的整体架构图?Buffer Pool / Change Buffer / Log Buffer / Data Dictionary 的作用?FULL
- 2Buffer Pool 的工作机制?LRU 链表是如何区分热点页和新页(midpoint insertion)的?FULL
- 3什么是 Change Buffer?什么场景下会让二级索引写更快?为什么对唯一索引无效?FULL
- 4什么是 Doublewrite Buffer?解决了什么问题?(页面部分写问题)FULL
- 5InnoDB 的页结构?File Header、Page Header、Infimum + Supremum、User Records、Page Directory 各自作用?FULL
- 6什么是行格式(Compact / Redundant / Dynamic / Compressed)?长字段如何溢出存储?FULL
- 7InnoDB 表为什么必须有主键?没指定主键时它会做什么?FULL
- 8InnoDB 为什么推荐用单调递增的主键?随机 UUID 主键的代价?FULL
§7
日志与恢复(redo / undo / binlog / 两阶段提交)
17 题7.1
redo log
7.2
undo log 与回滚
7.3
binlog 与两阶段提交
- 1binlog 是什么?相比 redo log 的本质区别?(server 层 vs 引擎层)FULL
- 2binlog 的三种格式 STATEMENT / ROW / MIXED 各自优缺点?FULL
- 3什么是两阶段提交(2PC)?为什么 redo log + binlog 必须两阶段提交?FULL
- 4两阶段提交的中间崩溃,如何恢复?(prepare、commit 标志位)FULL
- 5MySQL 通过什么机制保证 binlog 是完整的?(checksum、END_LOG_EVENT、写盘策略)FULL
- 6sync_binlog = 0 / 1 / N 各自含义?双 1 配置(redo + binlog)保证数据不丢的代价?FULL
- 7误删数据如何用 binlog 闪回?mysqlbinlog + 反向 SQL / binlog2sql 工具的工作原理?FULL
§8
主从复制与高可用
11 题8.1
复制原理
- 1MySQL 主从复制的整体流程?(binlog dump、IO thread、relay log、SQL thread)FULL
- 2异步复制、半同步复制、组复制(Group Replication)各自的差异和适用场景?FULL
- 3什么是 GTID?相比传统的 file+pos 定位有什么优势?FULL
- 4什么是主备延迟(seconds_behind_master)?常见原因和解决方法?FULL
- 5并行复制的几种策略:库级并行、组提交、WRITESET?performance_schema.replication_applier_status_by_worker?FULL
- 6binlog 的多线程复制为什么会出现写入冲突?怎么避免?FULL
§9
性能优化(执行计划 / 慢查询 / 常见陷阱)
26 题9.1
慢查询定位
9.2
SQL 改写优化
- 1SELECT * 为什么不推荐?什么时候 SELECT * 反而合理?FULL
- 2深分页 LIMIT 100000, 20 怎么优化?(子查询主键、记录上次最大主键、覆盖索引)FULL
- 3JOIN 大表时驱动表选择不当导致慢,怎么优化?FULL
- 4OR 查询索引失效怎么办?UNION 改写策略?FULL
- 5IN 列表过大(几千几万个值)怎么优化?(临时表、批量分组)FULL
- 6GROUP BY + ORDER BY 同时存在时如何避免临时表?FULL
- 7COUNT(*) 慢,是否可以用估算(information_schema.tables.table_rows)代替?FULL
- 8存在 WHERE 条件 + ORDER BY + LIMIT 的复合查询,怎么设计联合索引?FULL
9.3
Schema 与设计层优化
§10
数据建模与设计(范式 / 主键 / 分库分表)
16 题10.1
范式与反范式
10.2
主键与 ID 生成
§11
SQL 实战编程题(GitHub 高频题)
33 题11.1
查找类
11.2
Top N / 排名 / 分位数
11.3
数据透视 / 行列转换
11.4
时间序列与增长分析
§12
大厂 SQL 面试真题(字节 / 阿里 / 拼多多 / 滴滴 / 小红书 / Meta / Amazon)
22 题12.1
字节跳动 / TikTok
12.2
阿里 / 拼多多 / 美团
12.3