51mee - AI智能招聘平台Logo
模拟面试题目大全招聘中心会员专区

针对教育数据仓库中“按用户ID查询近30天课程完成率”的查询场景,设计索引、分区策略或数据模型优化方案,提升查询效率。

好未来数据仓库难度:中等

答案

1) 【一句话结论】针对按用户ID查询近30天课程完成率的场景,应采用复合索引(user_id + completion_date)+ 时间分区(按天分区)+ 星型数据模型(事实表+维度表关联),通过索引加速列扫描、分区减少数据扫描范围、模型优化减少关联复杂度,显著提升查询效率。

2) 【原理/概念讲解】
老师口吻解释核心概念:

  • 复合索引:类似书籍的“用户ID-日期”目录,查询时系统先按用户ID定位数据行,再按日期过滤,避免全表扫描。例如,查询条件包含“user_id=1001”和“completion_date在近30天”,复合索引能高效匹配这两个条件。
  • 时间分区:将数据按时间维度(如天、月)划分,比如每天一个分区。查询近30天时,只需扫描最近30个分区,大幅减少数据量。
  • 星型模式:事实表(如course_completion_fact)存储核心行为数据(用户ID、课程ID、完成时间等),维度表(用户、课程)存储描述性属性。事实表按维度表主键(如user_id、course_id)建立索引,查询时通过外键连接,索引加速关联。

3) 【对比与适用场景】

优化方案定义特性适用场景注意点
复合索引多列组合的B+树索引提升多列组合查询效率,减少I/O查询条件包含多个列(如user_id和date)索引列顺序影响效率,需按查询条件顺序排列
时间分区按时间维度(如天、月)划分数据减少查询扫描范围,按时间范围过滤时间序列查询(如近30天、近一年)分区粒度需平衡查询粒度和管理成本
星型模式事实表+维度表结构事实表存储行为,维度表存储属性,减少关联复杂度多维分析查询(如用户完成率、课程效果)维度表需建立主键索引,事实表按维度表主键关联

4) 【示例】
假设事实表course_completion_fact结构:

  • user_id (INT, PK)
  • course_id (INT, FK)
  • completion_date (DATE, 分区列)
  • is_completed (BOOLEAN)

维度表user_dim:

  • user_id (INT, PK)
  • user_name (VARCHAR)
  • user_level (INT)

维度表course_dim:

  • course_id (INT, PK)
  • course_name (VARCHAR)
  • course_type (INT)

查询优化后SQL(伪代码):

SELECT 
    u.user_name,
    c.course_name,
    COUNT(f.is_completed) AS completed_count,
    COUNT(*) AS total_count,
    (COUNT(f.is_completed) * 1.0 / COUNT(*)) AS completion_rate
FROM 
    course_completion_fact f
JOIN 
    user_dim u ON f.user_id = u.user_id
JOIN 
    course_dim c ON f.course_id = c.course_id
WHERE 
    f.user_id = ?  -- 用户ID
    AND f.completion_date BETWEEN DATE_SUB(CURDATE(), INTERVAL 30 DAY) AND CURDATE()
GROUP BY 
    u.user_name, c.course_name;

优化点:

  • 对course_completion_fact建立复合索引:CREATE INDEX idx_user_date ON course_completion_fact(user_id, completion_date);
  • 按completion_date分区:CREATE TABLE course_completion_fact (user_id INT, course_id INT, completion_date DATE, is_completed BOOLEAN) PARTITION BY RANGE (completion_date) (PARTITION p0 VALUES LESS THAN ('2023-01-01'), PARTITION p1 VALUES LESS THAN ('2023-02-01'), ...);
  • 维度表按主键建立索引:CREATE INDEX idx_user_id ON user_dim(user_id); CREATE INDEX idx_course_id ON course_dim(course_id);

5) 【面试口播版答案】
(约80秒)
“面试官您好,针对按用户ID查询近30天课程完成率的场景,核心优化思路是结合复合索引、时间分区、星型数据模型,具体来说:
首先,在事实表(如课程完成事实表)上建立复合索引(user_id + completion_date),查询时系统先按用户ID定位数据,再按日期过滤,避免全表扫描;
其次,对事实表按completion_date进行时间分区(按天分区),查询近30天时只需扫描最近30个分区,大幅减少数据量;
再者,采用星型模式,事实表存储核心行为数据(用户ID、课程ID、完成时间等),维度表(用户、课程)存储描述性属性,维度表按主键建立索引,查询时通过外键连接,索引加速关联。
这样,查询效率会显著提升,因为索引减少了I/O,分区减少了扫描范围,模型优化减少了关联复杂度。总结来说,通过复合索引+时间分区+星型模式,可以高效处理按用户ID和日期范围查询的课程完成率。”

6) 【追问清单】

  • 问:为什么选择复合索引而不是单列索引?
    答:因为查询条件包含user_id和completion_date两个列,复合索引能同时利用这两个列的排序,提升多列组合查询效率。
  • 问:时间分区的粒度(如天 vs 月)如何选择?
    答:天粒度更细,能支持更精确的查询(如按天统计),但管理成本高;月粒度粗,适合宏观分析,需根据业务查询频率和存储成本平衡。
  • 问:数据模型中,事实表和维度表如何关联?
    答:事实表通过外键(user_id、course_id)与维度表关联,查询时通过外键连接,索引加速关联,减少全表扫描。
  • 问:如果用户ID有大量数据,索引是否会导致存储开销大?
    答:复合索引的存储开销与列数和列类型有关,但相比全表扫描的I/O,索引开销较小,且能显著提升查询效率,可通过定期维护(如重建索引)优化。
  • 问:如何处理冷热数据?
    答:时间分区后,旧分区(如超过一年的数据)可归为冷数据,存储在低成本存储(如对象存储),查询时跳过冷分区,减少I/O。

7) 【常见坑/雷区】

  • 坑1:仅索引user_id,忽略completion_date,导致查询时仍需扫描全表,索引失效。
  • 坑2:分区粒度过细(如按小时分区),导致分区数量过多,管理复杂,查询时扫描分区列表开销大。
  • 坑3:数据模型设计为雪花模式,维度表过多,导致事实表与维度表连接时关联复杂,查询效率低。
  • 坑4:未考虑数据倾斜,比如某些用户ID的数据量远大于其他用户,导致索引或分区扫描不均衡。
  • 坑5:未优化查询的并发,比如分区表未设置并行查询,导致查询时单线程执行,效率低。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1