- 联合查询语句:
EXPLAIN
SELECT o.order_id, c.customer_name, p.product_name
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id
JOIN products p ON o.product_id = p.product_id;
- EXPLAIN 各字段分析:
- id:
- 标识 SELECT 语句的执行顺序。在复杂查询(如包含子查询或联合查询)中,不同的 SELECT 会有不同的 id 值,id 值越大越先执行。如果所有 SELECT 语句的 id 值相同,则按照自上而下的顺序执行。例如,在子查询中,子查询的 SELECT 可能会有更高的 id 值,先于外层查询执行。
- select_type:
- SIMPLE:表示简单的 SELECT,不包含子查询或 UNION。上述查询就是 SIMPLE 类型,说明查询结构较为直接,不涉及复杂的嵌套或联合操作,一般性能相对较好。
- PRIMARY:如果查询中包含子查询,最外层的 SELECT 就是 PRIMARY 类型。
- SUBQUERY:子查询中的第一个 SELECT 就是 SUBQUERY 类型。子查询会先于外层查询执行,且结果用于外层查询的条件判断等操作,如果子查询性能不佳,会影响整个查询性能。
- table:
- 显示当前查询访问的表。在上述查询中,会依次显示
orders
、customers
、products
,表示查询执行过程中依次访问这三张表。访问顺序对查询性能有影响,如果能按照合适的顺序访问表,利用索引等机制,可以提高查询效率。
- partitions:
- 对于分区表,显示查询访问的分区。如果表没有分区,该字段为空。例如,如果
orders
表按日期分区,查询某一时间段的订单,这里会显示具体访问的日期分区,合理的分区策略有助于减少单次查询的数据量,提升性能。
- type:
- ALL:全表扫描,查询会遍历表中的每一行数据,性能最差。如查询没有使用任何索引,对
orders
表进行全表扫描,会导致查询性能低下,因为要处理大量的数据行。
- index:索引扫描,扫描整个索引树,虽然比全表扫描快,但如果索引较大,也可能有性能问题。例如对一个有大量索引项的
customers
表进行索引扫描。
- range:范围扫描,通常是在索引上进行范围查找,如
WHERE column BETWEEN value1 AND value2
,性能较好。比如在 orders
表的 order_id
索引上进行范围查询,减少了扫描的数据量。
- ref:使用非唯一索引进行等值查询,通过索引找到匹配的行。如根据
customer_id
关联 orders
表和 customers
表时,如果 customer_id
上有索引,就可能是 ref 类型,性能较高。
- eq_ref:通常用于连接操作,在连接条件是主键或唯一索引的等值连接时出现。例如在
orders
表和 customers
表通过 customer_id
关联,且 customers
表的 customer_id
是主键时,该连接可能是 eq_ref 类型,这是非常高效的连接类型。
- possible_keys:
- 显示查询可能使用到的索引。例如,对于上述查询,
orders
表的 customer_id
和 product_id
索引、customers
表的 customer_id
索引、products
表的 product_id
索引可能都会显示在这里。这些索引为查询优化提供了潜在的路径,但并不一定都会被实际使用。
- key:
- 实际使用的索引。如果查询优化器选择使用了
orders
表的 customer_id
索引来关联 customers
表,这里就会显示 customer_id
索引名。正确选择使用的索引对查询性能至关重要,如果选错索引或没有使用索引,会导致查询性能下降。
- key_len:
- 显示实际使用索引的长度。它可以帮助判断索引使用的是否完整。例如,一个复合索引有多个字段,如果
key_len
小于复合索引所有字段长度之和,说明可能没有完全使用复合索引,需要进一步优化。
- ref:
- 显示哪些列或常量被用于查找索引列上的值。比如在
orders
表和 customers
表的连接中,如果使用 customer_id
索引,这里可能显示 customers.customer_id
,表示通过 customers
表的 customer_id
列来匹配 orders
表的 customer_id
索引。
- rows:
- 估计为了找到所需的行,需要扫描的行数。行数越少,查询性能越好。例如,如果查询估计只需要扫描
orders
表的 10 行数据,相比扫描 10000 行数据,性能会有很大提升。这只是一个估计值,实际行数可能因数据分布等因素有所不同。
- filtered:
- 表示存储引擎返回的数据在经过条件过滤后,满足查询条件的记录的百分比。例如,存储引擎返回了 100 行数据,经过 WHERE 条件过滤后,有 50 行满足条件,那么 filtered 就是 50%。这个值越高,说明查询条件过滤效果越好,查询性能相对越高。如果 filtered 值很低,可能需要优化查询条件或索引,以减少不必要的数据扫描。