面试题答案
一键面试索引选择原则
- 覆盖索引:
- 尽量使用覆盖索引,即查询所需要的所有数据都能从索引中获取,避免回表操作。例如,对于查询
SELECT column1, column2 FROM table WHERE condition;
,如果创建索引CREATE INDEX idx_column1_column2 ON table (column1, column2);
,当查询条件为column1
相关且要获取column1
和column2
时,就可以利用覆盖索引,减少磁盘I/O。原理是索引结构本身包含了相关列数据,不需要再通过索引查到主键后回表到聚簇索引获取数据,提升查询效率。
- 尽量使用覆盖索引,即查询所需要的所有数据都能从索引中获取,避免回表操作。例如,对于查询
- 前缀索引:
- 对于较长的字符串列,可以使用前缀索引。比如有一个
description
字段存储较长文本,创建CREATE INDEX idx_description ON table (description(10));
只对前10个字符创建索引。这样可以减少索引占用空间,提高索引维护效率。原理是通过对部分字符串创建索引,在一定程度上仍能快速定位数据,同时减少索引存储开销。
- 对于较长的字符串列,可以使用前缀索引。比如有一个
- 复合索引顺序:
- 复合索引的列顺序要遵循最左前缀原则。例如,对于查询
SELECT * FROM users WHERE country = 'USA' AND city = 'New York';
,创建CREATE INDEX idx_country_city ON users (country, city);
索引,MySQL能高效利用该索引,因为它从左到右匹配查询条件。原理是MySQL在使用复合索引时,先按第一个列进行排序查找,再在第一个列相同的基础上按第二个列查找等。
- 复合索引的列顺序要遵循最左前缀原则。例如,对于查询
减少并发问题策略
- 读写分离:
- 策略:使用主从复制架构,主库负责写操作,从库负责读操作。例如,一个新闻发布系统,用户发布新闻(写操作)在主库,大量用户浏览新闻(读操作)在从库。
- 原理:通过分离读写,减少主库读压力,同时从库可设置多个分担读负载,降低锁争用。主库写操作时,从库同步数据但不会影响读操作,因为从库读数据不受主库写锁影响。
- 合理选择锁粒度:
- 策略:能使用行锁尽量不使用表锁。例如,在电商库存系统中,更新某一商品库存时,使用行锁
SELECT... FOR UPDATE
语句锁定特定商品行。 - 原理:行锁只锁定相关行数据,相比表锁(锁定整个表),其他事务仍可操作表内其他行数据,降低锁争用范围,提高并发性能。
- 策略:能使用行锁尽量不使用表锁。例如,在电商库存系统中,更新某一商品库存时,使用行锁
- 乐观锁:
- 策略:在更新数据时,基于版本号或时间戳机制。比如在用户信息修改场景,表中添加
version
字段,更新前先获取当前version
,更新时带上version
并验证,若version
与获取时相同则更新并version + 1
,否则重试。 - 原理:乐观锁假设并发冲突概率低,不预先加锁,只有在更新时检查数据是否被其他事务修改,减少锁等待时间,提升并发性能。
- 策略:在更新数据时,基于版本号或时间戳机制。比如在用户信息修改场景,表中添加