MST

星途 面试题库

面试题:MySQL索引优化:高级难度之索引与查询执行计划

假设有一个订单表orders,包含字段order_id(主键)、customer_id、order_date、total_amount等。现有一个查询语句:SELECT * FROM orders WHERE customer_id = 123 AND order_date > '2023 - 01 - 01' ORDER BY total_amount LIMIT 10; 如何通过分析查询执行计划(EXPLAIN)来判断当前索引是否合理?如果不合理,应如何调整索引?详细阐述分析过程及调整策略。
31.0万 热度难度
数据库MySQL

知识考点

AI 面试

面试题答案

一键面试
  1. 使用EXPLAIN分析查询执行计划
    • 在SQL查询前加上EXPLAIN关键字,即EXPLAIN SELECT * FROM orders WHERE customer_id = 123 AND order_date > '2023 - 01 - 01' ORDER BY total_amount LIMIT 10;
    • 分析EXPLAIN结果
      • id:该列是查询中每个SELECT子句的标识符。通常为1,如果有子查询或联合查询,会有不同的编号。一般不直接用于判断索引合理性,但可辅助判断查询结构。
      • select_type:显示SELECT的类型,常见的有SIMPLE(简单SELECT,不包含子查询或联合查询)等。这里通常为SIMPLE
      • table:显示这一行数据是关于哪张表的。
      • partitions:如果表是分区表,会显示查询涉及的分区。
      • type:表示表的连接类型,常见的值有ALL(全表扫描)、index(索引扫描)、range(范围扫描)、ref(非唯一索引扫描,使用普通索引)、eq_ref(唯一索引扫描,常用于连接条件是主键或唯一键的情况)、const(常量连接,查询条件能确定唯一一行数据)等。理想情况下,这里应该是rangeref类型,如果是ALL,则说明可能没有用上合适的索引。
      • possible_keys:显示查询可能使用到的索引。
      • key:实际使用的索引。如果key为空,而possible_keys有值,说明虽然有可用索引,但查询没有使用,可能索引选择不合理。
      • key_len:显示索引中使用的字节数,可帮助判断使用了索引的哪些部分。
      • ref:显示哪些列或常量与索引进行比较。
      • rows:估计为了找到所需的行要读取的行数。行数越少越好,全表扫描时这个值通常较大。
      • filtered:表示表中满足条件的行所占的百分比。
  2. 判断索引是否合理
    • 不合理情况一typeALLkey为空,说明进行了全表扫描,未使用任何索引,当前索引不合理。
    • 不合理情况二typeindex,但扫描行数过多,且key使用的索引并非最优,可能没有覆盖到最有效的查询条件。例如,可能有更合适的复合索引未被使用。
  3. 调整索引策略
    • 创建复合索引:根据查询条件customer_id = 123 AND order_date > '2023 - 01 - 01' ORDER BY total_amount,可以考虑创建一个复合索引CREATE INDEX idx_customer_date_amount ON orders (customer_id, order_date, total_amount);。这样的复合索引在查询时,MySQL可以利用索引的最左前缀原则,先根据customer_id过滤,再根据order_date进行范围扫描,并且在排序时也能利用索引,提高查询效率。
    • 注意:索引并非越多越好,过多的索引会增加数据插入、更新和删除操作的开销,因为每次数据变动都需要更新相应的索引。所以在添加索引后,要全面评估对整个系统性能的影响。