
1) 【一句话结论】处理百万级数学试题的数据库查询优化,核心是通过复合索引加速多条件筛选、分库分表水平拆分数据、查询缓存减少重复查询,结合数据库引擎优化与分页策略,实现高效筛选。
2) 【原理/概念讲解】
针对“按知识点、难度筛选题目”的场景,需从查询效率、数据量扩展性、缓存复用三方面优化:
3) 【对比与适用场景】
| 方法 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 复合索引 | 多列组合的索引(如知识点+难度) | 提升多条件查询效率,减少全表扫描 | 按知识点、难度等维度筛选题目 | 索引列顺序需按查询频率排序,避免冗余 |
| 分库分表 | 水平拆分数据到多个数据库/表(如按知识点拆分表) | 扩展性,降低单库压力,提升并发处理能力 | 数据量超百万,单库性能瓶颈 | 需处理数据一致性(如分布式事务),拆分策略(如范围分片、哈希分片) |
| 查询缓存 | 存储查询结果(如按知识点+难度筛选的题目列表) | 减少数据库重复查询,提升响应速度 | 高频查询(如常见题型、热门知识点) | 需考虑缓存失效(TTL),避免数据不一致 |
4) 【示例】
数据库表结构(题库表):
CREATE TABLE 题库 (
id INT PRIMARY KEY,
知识点 VARCHAR(50),
难度 VARCHAR(20),
题目内容 TEXT,
创建时间 TIMESTAMP
);
建复合索引:
CREATE INDEX idx_knowledge_difficulty ON 题库 (知识点, 难度);
优化查询(按知识点“函数”和难度“中等”筛选,分页10条):
SELECT id, 题目内容
FROM 题库
WHERE 知识点 = '函数' AND 难度 = '中等'
ORDER BY id
LIMIT 10, 10; -- 分页查询,id是主键,索引覆盖(无需回表)
解释:数据库通过复合索引(知识点+难度)快速定位行,因id是主键,索引覆盖,避免回表,提升速度。
缓存示例(Redis存储热门查询结果):
# 缓存键:knowledge_difficulty:函数:中等:10(表示函数-中等-前10条)
SET knowledge_difficulty:函数:中等:10 '{"id":1,"内容":"求函数f(x)=...的值"}'
EXPIRE knowledge_difficulty:函数:中等:10 1800; -- 30分钟过期
后续查询直接从Redis获取,避免数据库查询。
5) 【面试口播版答案】
“面试官您好,处理百万级数学试题的查询优化,核心是结合索引优化、分库分表、查询缓存。首先,针对知识点和难度这两个筛选条件,我会为表建立复合索引(知识点+难度),因为这是查询的常用条件,能大幅减少全表扫描。比如,当用户按‘代数’知识点和‘中等’难度筛选时,数据库可以直接用索引定位,避免扫描百万条数据。其次,数据量太大时,考虑分库分表,比如按知识点或难度范围拆分表,比如‘函数’知识点单独一个库,减少单库压力。然后,对于高频查询(如常见题型),用Redis缓存存储结果,比如缓存‘代数-中等’的10道题,后续请求直接从缓存取,不用数据库。另外,分页查询时用覆盖索引,避免回表,提升性能。这样组合起来,就能高效处理百万级题库的筛选了。”
6) 【追问清单】
7) 【常见坑/雷区】