面试题答案
一键面试- 使用
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
(常量连接,查询条件能确定唯一一行数据)等。理想情况下,这里应该是range
或ref
类型,如果是ALL
,则说明可能没有用上合适的索引。possible_keys
:显示查询可能使用到的索引。key
:实际使用的索引。如果key
为空,而possible_keys
有值,说明虽然有可用索引,但查询没有使用,可能索引选择不合理。key_len
:显示索引中使用的字节数,可帮助判断使用了索引的哪些部分。ref
:显示哪些列或常量与索引进行比较。rows
:估计为了找到所需的行要读取的行数。行数越少越好,全表扫描时这个值通常较大。filtered
:表示表中满足条件的行所占的百分比。
- 在SQL查询前加上
- 判断索引是否合理:
- 不合理情况一:
type
为ALL
,key
为空,说明进行了全表扫描,未使用任何索引,当前索引不合理。 - 不合理情况二:
type
为index
,但扫描行数过多,且key
使用的索引并非最优,可能没有覆盖到最有效的查询条件。例如,可能有更合适的复合索引未被使用。
- 不合理情况一:
- 调整索引策略:
- 创建复合索引:根据查询条件
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
进行范围扫描,并且在排序时也能利用索引,提高查询效率。 - 注意:索引并非越多越好,过多的索引会增加数据插入、更新和删除操作的开销,因为每次数据变动都需要更新相应的索引。所以在添加索引后,要全面评估对整个系统性能的影响。
- 创建复合索引:根据查询条件