MST

星途 面试题库

面试题:MySQL Query Browser界面下如何优化复杂查询的执行计划

在MySQL Query Browser中有一个复杂查询,涉及多个表的连接以及子查询,查询执行时间较长。请阐述如何在该界面中查看查询的执行计划,根据执行计划分析可能存在的性能问题,并说明至少三种优化该查询的方法及在MySQL Query Browser中的操作流程。
37.8万 热度难度
数据库MySQL

知识考点

AI 面试

面试题答案

一键面试

查看查询执行计划

在MySQL Query Browser中,在查询语句前加上 EXPLAIN 关键字,然后执行该查询,执行结果会展示查询的执行计划。例如:

EXPLAIN SELECT * FROM table1 JOIN table2 ON table1.id = table2.id WHERE table1.column = 'value';

执行上述查询后,会显示如下信息(以表格形式呈现,不同版本可能字段有差异):

  1. id:查询中每个 SELECT 子句的标识符,id相同表示查询是在同一层次,id不同表示子查询。
  2. select_typeSELECT 类型,常见有 SIMPLE(简单查询,不包含子查询和联合查询)、PRIMARY(最外层的查询)、SUBQUERY(子查询)等。
  3. table:输出的行数据来自哪张表。
  4. partitions:匹配的分区。
  5. type:连接类型,如 ALL(全表扫描)、index(索引扫描)、range(范围扫描)、ref(使用非唯一索引扫描)等,ALL 性能最差,应尽量避免。
  6. possible_keys:可能使用到的索引。
  7. key:实际使用到的索引。
  8. key_len:索引使用的字节数,可评估索引使用效率。
  9. ref:显示使用哪个列或常数与索引进行比较。
  10. rows:预估扫描的行数,行数越少通常性能越好。
  11. filtered:预估条件过滤后返回的行百分比。

分析可能存在的性能问题

  1. 全表扫描(type为ALL):如果某个表的连接类型为 ALL,表示对该表进行全表扫描,这在数据量较大时性能较差,应考虑添加合适的索引。
  2. 未使用索引(key为NULL)possible_keys 有索引,但 keyNULL,说明查询未使用预期的索引,可能需要调整查询语句或索引结构。
  3. 过多的临时表和文件排序:如果执行计划中出现 Using temporaryUsing filesort,表示MySQL需要创建临时表或进行文件排序,这会影响性能。

优化查询的方法及操作流程

  1. 添加索引
    • 分析:根据执行计划中显示的未使用索引的情况,添加合适的索引。例如,如果 typeALLpossible_keys 为空,针对 WHERE 子句中的条件列添加索引。
    • 操作流程:在MySQL Query Browser中使用 CREATE INDEX 语句创建索引。例如,给 table1 表的 column 列添加普通索引:
CREATE INDEX idx_column ON table1(column);
  1. 优化子查询
    • 分析:子查询可能导致多次扫描数据库,可以将子查询改写为连接查询,减少查询次数。例如,子查询 SELECT column FROM table2 WHERE id IN (SELECT id FROM table1 WHERE condition),可改写为连接查询 SELECT table2.column FROM table1 JOIN table2 ON table1.id = table2.id WHERE table1.condition
    • 操作流程:直接在查询语句中改写子查询为连接查询形式,然后重新执行并查看执行计划,确认性能是否提升。
  2. 使用覆盖索引
    • 分析:如果查询只需要索引列的值,覆盖索引可以避免回表操作,提高性能。例如,查询 SELECT column1, column2 FROM table1 WHERE condition,若 column1column2 已包含在某个索引中,则该索引为覆盖索引。
    • 操作流程:通过 CREATE INDEX 创建复合索引,将查询涉及的列都包含在索引中。例如:
CREATE INDEX idx_columns ON table1(column1, column2);
  1. 调整连接顺序
    • 分析:不同的表连接顺序可能会影响查询性能,MySQL Query Optimizer会尝试选择最优顺序,但有时手动调整可能更好。通常将数据量小的表放在前面连接。
    • 操作流程:直接在查询语句中调整 JOIN 子句中表的顺序,重新执行查询并查看执行计划,对比性能。
  2. 分区表
    • 分析:如果表数据量非常大,可以考虑对表进行分区,将数据分散存储,减少单次查询的数据量。例如,按日期对日志表进行分区。
    • 操作流程:使用 CREATE TABLE 语句创建分区表。例如,按日期范围分区:
CREATE TABLE log_table (
    id INT,
    log_date DATE,
    log_content TEXT
)
PARTITION BY RANGE (YEAR(log_date)) (
    PARTITION p0 VALUES LESS THAN (2020),
    PARTITION p1 VALUES LESS THAN (2021),
    PARTITION p2 VALUES LESS THAN (2022)
);

然后将原表数据导入到分区表,并调整查询语句查询分区表。