mysql 通过 2 种方式加入 - 它是如何工作的?- 这给出了性能差异

niz*_*zha 5 mysql join explain

我有 2 种不同的方式来查询在执行时表现出性能差异的内容。第一种方法是

EXPLAIN select SOME_COLUMNS
from
( select *
  from A
  where CONDITION
) p
inner join
( select *
  from B
)st
on p.id = st.id;
Run Code Online (Sandbox Code Playgroud)

此查询的输出返回:

"id"   "select_type"   "table"    "type"   "possible_keys"   "key"    "key_len"   "ref"   "rows"   "Extra"

 1       PRIMARY     derived3  ALL       NULL                 NULL    NULL    NULL      25607     "   "
 1        PRIMARY    derived2  ALL        NULL                NULL     NULL    NULL      21037   Using where; Using join buffer
 3        DERIVED             A    ALL          NULL               NULL      NULL    NULL      23202    "   "
 2        DERIVED             B    ref        IDX_A_TYPE_ID   IDX_A_ID  98      "   "        12411  Using where
Run Code Online (Sandbox Code Playgroud)

另一种方式是

EXPALIN SELECT SOME_COLUMNS
FROM A p, B s
WHERE p.id = s.id
AND p.CONDITION;
Run Code Online (Sandbox Code Playgroud)

其输出如下所示:

id       select_type       table       type       possible_keys       key     key_len    ref     rows   Extra
 1       SIMPLE           p            ref       PRIMARY,IDX_A_TYPE_ID      IDX_A_TYPE_ID    98    const    12411    Using where
 1      SIMPLE            s           ref             PRIMARY       PRIMARY     4   local_db.p.entity_id    1  
Run Code Online (Sandbox Code Playgroud)

为什么在查询执行的每个步骤中获取的行数在 2 和第 1 种方法中获取的行数之间存在如此大的差异?请解释一下。

小智 1

存在差异是因为:

  1. 在第一个查询中执行以下操作:

    • A使用过滤出的数据创建临时表CONDITION
    • 使用以下数据创建临时表B
    • 对于 中的每一行,temp_A我们都遍历temp_B. 在本例中temp_A使用 FULL SCAN,temp_B通过索引访问
  2. 第二次查询

    • 对于A属于我们的每一行,CONDITION我们都与 table 连接B

正如您在第二个查询中看到的,有“预加载”数据到表中,并且扫描以不同的方式工作。