面试题答案
一键面试索引策略设计
- 按用户ID查询近期发布的帖子(按创建时间排序)
- 创建复合索引
(user_id, create_time)
。根据MySQL索引列顺序选择原则,将user_id
放在前面,因为它是主要的过滤条件,create_time
放在后面以支持按创建时间排序。这样在查询时,MySQL可以快速定位到指定用户的记录,然后按创建时间顺序读取。
- 创建复合索引
- 按点赞数查询热门帖子
- 创建索引
(like_count)
。如果经常按点赞数从高到低查询热门帖子,单独对like_count
建立索引可以加快查询速度。
- 创建索引
- 按评论数查询热门帖子
- 创建索引
(comment_count)
。与按点赞数查询类似,单独对comment_count
建立索引,便于快速查询热门帖子。
- 创建索引
避免索引争用等性能问题的方法
- 高并发写入操作
- 批量写入:尽量采用批量插入的方式,减少单个写入操作的次数,从而减少对索引的频繁更新。例如,使用
INSERT INTO posts (post_id, user_id, create_time, like_count, comment_count) VALUES (1, 100, '2023 - 10 - 01 12:00:00', 0, 0), (2, 100, '2023 - 10 - 01 12:01:00', 0, 0);
这种批量插入语句,而不是多次执行单个INSERT
语句。 - 写入队列:引入消息队列(如Kafka等),将写入请求先放入队列中,然后由后台服务按顺序消费队列中的消息进行写入操作。这样可以削峰填谷,避免瞬间大量的写入请求同时竞争索引资源。
- 合理安排索引更新时机:可以在业务允许的情况下,将索引更新操作延迟到业务低谷期进行。例如,在凌晨等用户活跃度较低的时候,对一些统计类索引(如点赞数、评论数等相关索引)进行批量更新。
- 批量写入:尽量采用批量插入的方式,减少单个写入操作的次数,从而减少对索引的频繁更新。例如,使用
- 高并发读取操作
- 缓存机制:引入缓存(如Redis),将经常查询的数据(如热门帖子信息)缓存在Redis中。当有读取请求时,先从缓存中获取数据,如果缓存中没有,再查询数据库,并将查询结果更新到缓存中。这样可以大大减轻数据库的读取压力,减少对索引的频繁访问。
- 读写分离:采用主从复制架构,主库负责写入操作,从库负责读取操作。从库可以设置多个,将读取请求均匀分配到各个从库上,避免单个数据库实例承受过高的读取压力,从而减少索引争用的可能性。
- 优化查询语句:确保查询语句尽可能简单和高效,避免复杂的
JOIN
操作和全表扫描。在编写查询语句时,充分利用已建立的索引,通过使用EXPLAIN
关键字分析查询计划,确保查询按照预期使用索引。