如何确定在读取EXPLAIN查询计划时访问的总行数



我正在阅读MySQL文档,了解如何解释EXPLAIN计划的结果。我在顶部看到以下段落:

EXPLAIN为SELECT中使用的每个表返回一行信息陈述它按MySQL会在处理声明时阅读它们。这意味着MySQL从第一个表中读取一行,然后在第二个表,然后在第三个表,依此类推。当所有表处理,MySQL输出选定的列并回溯浏览表列表,直到找到一个表匹配的行。从该表中读取下一行,然后处理继续下表。

如果我正确地解释了这一点,这意味着可以通过乘以";行";每个表的部分,因为如果表1的每一行都可以有表2的一行,等等

举个例子,下面是我试图调试的一个查询:

SELECT DISTINCT DISTINCT roles.id, roles.* 
FROM `roles` 
INNER JOIN `resources` 
ON `resources`.`role_id` = `roles`.`id` 
INNER JOIN `resources` `workspace_resources_roles` 
ON `workspace_resources_roles`.`role_id` = `roles`.`id` 
AND `workspace_resources_roles`.`type` 
IN ('WorkspaceResource') 
INNER JOIN workspaces 
ON resources.subject_id = workspaces.id 
AND resources.subject_type = "Workspace" 
WHERE `roles`.`account_id` = 6804175 
AND `roles`.`deleted_at` IS NULL 
AND `resources`.`type` = 'WorkspaceResource' 
AND `resources`.`user_id` IS NULL 
AND `workspaces`.`archived` = FALSE 
AND `workspaces`.`account_id` = 6804175 
AND `roles`.`id` = 1205685 
ORDER BY roles.name ASC

以下是其解释计划:

id  1
select_type SIMPLE
table   roles
partitions  NULL
type    const
possible_keys   PRIMARY,index_roles_on_account_id_and_deleted_at_and_name,index_roles_on_account_id
key PRIMARY
key_len 4
ref const
rows    1
filtered    100.0
Extra   Using temporary
id  1
select_type SIMPLE
table   resources
partitions  NULL
type    index_merge
possible_keys   index_resources_on_user_id,index_resources_on_role_id,index_resources_on_type,index_resources_on_subject_id_and_subject_type,index_resources_on_subject_id
key index_resources_on_role_id,index_resources_on_user_id
key_len 5,5
ref NULL
rows    4075
filtered    2.5
Extra   Using intersect(index_resources_on_role_id,index_resources_on_user_id); Using where; Distinct
id  1
select_type SIMPLE
table   workspaces
partitions  NULL
type    eq_ref
possible_keys   PRIMARY,index_workspaces_on_account_id
key PRIMARY
key_len 4
ref mavenlink_production.resources.subject_id
rows    1
filtered    5.0
Extra   Using where; Distinct
id  1
select_type SIMPLE
table   workspace_resources_roles
partitions  NULL
type    ref
possible_keys   index_resources_on_role_id,index_resources_on_type
key index_resources_on_role_id
key_len 5
ref const
rows    32620
filtered    50.0
Extra   Using where; Distinct

表1有1行,表2有4075行,表3有1行和表4有32620行。在最坏的情况下,这是否意味着1*4075*1*32620=132936500行的总结果集?如果是这样的话,这就解释了为什么这个查询在我们的生产环境中需要173秒。

您在解释EXPLAIN方面走在了正确的轨道上。您有一个没有子查询的简单查询,并且将每个联接表的rows相乘。根据优化器计算的估计,这大致是要检查的行数。

请注意,优化器的估计值相当粗略。不要认为它们是准确的。

如果您有子查询,或者使用LIMIT,那么这种解释所检查行的方法会变得更加复杂。

如果您想要一个真实的测量,而不是EXPLAIN的估计,那么执行查询(不使用EXPLAIN(,并运行SHOW SESSION STATUS LIKE 'Handler%';。它将向您显示存储引擎运行的操作数量。像Handler_read_next或Handler_read_rnd这样的操作对应于检查的行。在两次测试之间运行FLUSH STATUS,将会话状态值清零。

最新更新