面试题答案
一键面试性能陷阱
- 索引冗余:在表中创建多个含义相近或部分重叠的索引。例如,已有索引
(col1, col2)
,又创建单独的(col1)
索引。这会增加数据插入、更新和删除操作的成本,因为每次数据变动,所有相关索引都要更新。 - 索引列顺序不当:在复合索引中,列的顺序非常关键。例如,对于查询
WHERE col2 = 'value' AND col1 = 'value'
,若索引是(col1, col2)
,数据库无法有效利用该索引进行col2
的快速查找,导致全索引扫描或全表扫描,影响查询性能。 - 过度索引:给表的每个列都创建索引,虽然在查询时某些情况下能提高速度,但极大增加了索引维护成本。插入、更新和删除操作时,数据库不仅要更新数据,还要更新多个索引,降低写操作性能,同时占用过多磁盘空间。
- 索引未覆盖查询:如果查询涉及的列没有全部包含在索引中,数据库可能需要回表操作。例如,索引是
(col1, col2)
,但查询SELECT col1, col2, col3 FROM table WHERE col1 = 'value'
,因为col3
不在索引中,需要从索引找到数据行主键后再回表获取col3
的值,增加了 I/O 操作。
避免方法
- 定期审查索引:定期检查数据库中的索引,使用
EXPLAIN
语句分析查询执行计划,找出冗余索引并删除。例如,对于上述提到的冗余索引情况,可通过分析查询需求和实际执行计划,删除不必要的(col1)
索引。 - 合理设计复合索引顺序:根据常见查询条件中列的使用频率和选择性来确定复合索引列的顺序。一般将选择性高(即该列不同值数量多)的列放在前面。例如,对于常见查询
WHERE col1 = 'value' AND col2 = 'value'
,应创建索引(col1, col2)
。 - 谨慎创建索引:在创建索引前,充分评估业务需求,只对经常用于
WHERE
子句、JOIN
条件或排序的列创建索引。避免为很少用于查询条件的列创建索引。 - 使用覆盖索引:设计索引时尽量让索引覆盖查询涉及的所有列。如上述查询,若经常出现,可创建索引
(col1, col2, col3)
,这样查询时可直接从索引获取所需数据,避免回表操作,提高查询性能。