第3章 高频技术面试题:SQL与数据查询优化

本章学习目标:掌握窗口函数底层机制、慢SQL排查方法论、用户行为分析SQL建模能力。本章覆盖三类核心面试题——窗口函数对比、查询性能优化、留存分析SQL,并配套回答框架与追问路径图。
函数 编号特点 典型场景 关键差异
ROW_NUMBER() 连续编号,无重复 分页查询、去重标记 同值不同号,严格递增
RANK() 同值同排名,跳号 并列排名、竞赛榜单 产生序号断层
DENSE_RANK() 同值同排名,不跳号 密集排名、TopN截取 排名连续无间隙
NTILE(n) 平均分桶编号 数据分片、等频划分 指定桶数均匀分组
LAG/LEAD 前后行偏移访问 环比计算、差值分析 offset控制偏移行数
SQL查询优化五步法(回答框架) 定位慢SQL 步骤1 分析执行计划 步骤2 识别性能瓶颈 步骤3 实施优化方案 步骤4 验证迭代监控 每个步骤可结合 EXPLAIN 输出、索引分析、Shuffle 日志等工具落地 SQL优化面试追问方向 SQL查询优化 如何定位慢SQL? 索引失效怎么办? 数据倾斜如何优化? 怎样验证效果? 面试官会从四个方向随机深入,考察候选人的系统化优化能力

📌 卡片1 · 窗口函数对比:ROW_NUMBER / RANK / DENSE_RANK

面试问题:请解释 ROW_NUMBER()、RANK() 和 DENSE_RANK() 的区别,并举例说明各自的使用场景。

🎯 面试官考察点:

  • 是否理解窗口函数底层排序+编号机制
  • 能否快速区分三者在“同值处理”上的核心差异
  • 是否具备将函数匹配到真实业务场景的能力

📐 回答框架:

  1. 定义区别 —— 三者都是排序编号函数,但处理同值的方式不同
  2. 对比关键差异 —— ROW_NUMBER 连续不重复,RANK 同值同排名后跳跃,DENSE_RANK 同值同排名不跳跃
  3. 场景举例 —— TopN用 DENSE_RANK,分页用 ROW_NUMBER,并列排名用 RANK

💬 示例回答:

三者都用于排名编号。ROW_NUMBER() 顺序递增不重复;RANK() 同值同排名但跳号产生断层;DENSE_RANK() 同值同排名且不跳号。取 TopN 用 DENSE_RANK 保证排名连续,分页查询用 ROW_NUMBER 精确控制行数,竞赛榜单用 RANK 保留并列跳跃语义。

🔍 可能追问:

  • 窗口函数与 GROUP BY 的执行顺序有什么区别?
  • 如果同时使用 PARTITION BY 和 ORDER BY,窗口函数的计算逻辑如何?
  • ROW_NUMBER 去重时要注意什么陷阱?
⚠️ 避坑提醒:不要混淆 RANK 与 DENSE_RANK 的跳跃逻辑——RANK 跳过后续序号(如 1,1,3),DENSE_RANK 不跳(如 1,1,2)。ROW_NUMBER 不可用于并列排名场景,否则会丢失同值语义。

📌 卡片2 · SQL查询优化:慢SQL排查与性能调优

面试问题:一条慢SQL你怎么排查和优化?请结合实际案例说明。

🎯 面试官考察点:

  • 是否具备系统化的性能分析思维(定位→分析→优化→验证)
  • 是否熟练使用 EXPLAIN、慢查询日志等工具
  • 优化方案是否具体可落地,而非空谈“加索引”

📐 回答框架:

  1. 定位问题 —— 通过慢查询日志或监控工具找到目标SQL
  2. 分析瓶颈 —— 使用 EXPLAIN 查看扫描行数、type类型、索引使用情况
  3. 实施优化 —— 索引优化 / SQL改写 / 参数调优 / 数据倾斜处理
  4. 验证效果 —— 对比执行时间、扫描行数、资源消耗

💬 示例回答:

先用慢查询日志定位SQL,EXPLAIN 发现全表扫描且未命中索引。添加联合索引后查询从3.2s降至0.05s。同时使用覆盖索引避免回表,大表分页改用游标替代 OFFSET,减少扫描行数。最后通过监控确认优化效果并配置告警阈值。

🔍 可能追问:

  • 什么情况下索引会失效?(隐式类型转换、不等值条件、Like前缀模糊等)
  • 如何判断是否需要重建索引?查看索引碎片率与实际选择性
  • EXPLAIN 中的 type 字段从好到差分别是哪些?
⚠️ 避坑提醒:不要只说“加索引”,要说明为什么加这个索引以及如何验证效果。一定要结合 EXPLAIN 输出分析,展示