面试题答案
一键面试1. 索引选择性较低的局限性
- 分析:索引选择性是指索引中不同值的数量与表中记录总数的比例。选择性低意味着很多记录在索引列上具有相同的值。当MySQL查询优化器基于这样的索引进行查询时,它可能无法有效缩小扫描范围,仍需扫描大量数据,导致查询性能低下。
- 举例:假设一个表
employees
有10000条记录,其中department
列只有5个不同的值(如销售、研发、财务、行政、客服),为department
列创建索引。如果执行查询SELECT * FROM employees WHERE department = '销售';
,由于选择性低,优化器可能还是需要扫描大量记录,索引效果不佳。 - 避免方法:考虑在更具选择性的列上创建索引,或者结合其他列创建复合索引来提高选择性。例如,如果
department
列和job_title
列结合起来有更多不同组合,可创建复合索引(department, job_title)
。
2. 复合索引最左前缀原则对优化器的限制
- 分析:复合索引遵循最左前缀原则,即MySQL查询优化器只有在查询条件中使用了复合索引最左边的列时,才会使用该复合索引。如果跳过最左边的列直接使用后面的列,索引将不会被使用。
- 举例:假设有一个复合索引
(col1, col2, col3)
,查询SELECT * FROM table WHERE col2 = 'value';
,优化器不会使用这个复合索引,因为没有从最左边的col1
开始使用。 - 避免方法:在设计复合索引时,要根据常用查询条件,将最常作为查询条件的列放在最左边。并且在编写查询语句时,尽量遵循最左前缀原则。如果确实需要跳过最左边的列查询,可以考虑对相关列单独创建索引。
3. 优化器在处理索引覆盖查询时可能出现的误判
- 分析:索引覆盖查询是指查询所需的数据都可以从索引中获取,无需回表操作。但优化器可能误判,即使可以使用索引覆盖查询,也不选择这种方式,导致额外的回表操作,增加查询开销。
- 举例:假设有表
users
包含id
,name
,email
列,创建索引(id, name)
。查询SELECT id, name FROM users WHERE id = 1;
理论上可以使用索引覆盖查询,但优化器可能误判,仍然执行回表操作去获取数据。 - 避免方法:可以通过使用
EXPLAIN
关键字查看查询执行计划,确认是否使用了索引覆盖查询。如果没有,可以尝试调整索引结构,比如将email
也包含进索引(前提是数据量合适,避免索引过大),变为(id, name, email)
,以引导优化器使用索引覆盖查询。同时,也可以通过提示(如MySQL 8.0支持的FORCE INDEX
等)来强制优化器使用特定索引策略。