MySQL中EXPLAIN ANALYZE的actual rows含义及执行顺序疑问
关于MySQL EXPLAIN ANALYZE中actual rows的疑问
执行的SQL查询
explain analyze select ep1_0.employee_post_id, ep1_0.access_url, ep1_0.contact, ep1_0.contents, ep1_0.member_id, ep1_0.payment_amount, ep1_0.payment_method, ep1_0.title, ep1_0.career_year, ep1_0.created_at, ep1_0.updated_at from employee_post ep1_0 join member m1_0 on m1_0.member_id=ep1_0.member_id where ep1_0.work_field_tag_id=1 order by ep1_0.created_at desc, ep1_0.employee_post_id desc limit 0,1;
得到的执行计划
-> Limit: 1 row(s) (cost=1088 rows=1) (actual time=23.8..23.8 rows=1 loops=1) -> Nested loop inner join (cost=1088 rows=1968) (actual time=23.8..23.8 rows=1 loops=1) -> Sort: ep1_0.created_at DESC, ep1_0.employee_post_id DESC (cost=399 rows=1968) (actual time=23.8..23.8 rows=1 loops=1) -> Index lookup on ep1_0 using FK_work_field_tag_TO_employee_post (work_field_tag_id=1) (cost=399 rows=1968) (actual time=0.069..5.12 rows=1968 loops=1) -> Single-row covering index lookup on m1_0 using PRIMARY (member_id=ep1_0.member_id) (cost=0.25 rows=1) (actual time=0.0262..0.0262 rows=1 loops=1)
疑问内容
无法理解MySQL中括号内的actual rows值的含义。在Nested loop inner join中,actual rows = 1是否表示实际仅关联了一行?如果是这样,是否说明JOIN是在应用LIMIT子句之后处理的?
解答
1. actual rows的含义
actual rows是EXPLAIN ANALYZE特有的字段,代表该执行步骤实际运行时返回的行数,是数据库真实处理的记录数量,和cost后的预估行数(理论计算值)区分开。
2. Nested loop inner join中actual rows=1的意义
是的,这里确实表示嵌套循环连接实际只输出了1行结果。这是MySQL优化器的提前终止优化导致的:
因为你的查询带有LIMIT 0,1,排序阶段不需要把所有符合条件的1968条记录全排序完,只需要找到排序后的Top 1记录就停止,然后把这1条记录传给嵌套循环连接步骤,和member表做关联,得到1条最终结果后,整个查询就满足了LIMIT的要求,直接终止后续处理,不会再处理剩下的1967条employee_post记录。
3. JOIN和LIMIT的执行顺序
并不是JOIN在LIMIT之后执行,而是优化器将LIMIT的逻辑提前到了JOIN阶段:
- 首先从
employee_post表中查出所有1968条符合work_field_tag_id=1的记录; - 排序阶段因为LIMIT的存在,只处理到能得到排序后的第一条记录就停止,返回1行给上层;
- 嵌套循环连接基于这1条记录,关联
member表得到1条结果; - 最后Limit阶段确认输出1行,完成查询。
内容的提问来源于stack exchange,提问作者dionisos198
相关产品推荐
相关产品推荐

