MySQL EXPLAIN 显示 ALL 类型,尽管 INDEX 存在

MySQL EXPLAIN showing ALL type although INDEX exists

我 运行 下面的查询使用 EXPLAIN

EXPLAIN SELECT form.id           AS `Reference No.`, 
               department.name   AS `Department`, 
               section.name      AS `Section` 
FROM   form 
       JOIN department 
         ON form.deptid = department.id 
       JOIN section 
         ON form.sectid = section.id 

在第一行输入 ALL 是否表示将出现性能问题?

+----+-------------+------------+--------+---------------+---------+---------+----------------------+------+
| id | select_type |   table    |  type  | possible_keys |   key   | key_len |         ref          | rows |
+----+-------------+------------+--------+---------------+---------+---------+----------------------+------+
|  1 | SIMPLE      | form       | ALL    | deptid,sectid |         |         |                      |  779 |
|  1 | SIMPLE      | department | eq_ref | PRIMARY       | PRIMARY |       4 | wfs-test.form.deptid |    1 |
|  1 | SIMPLE      | section    | eq_ref | PRIMARY       | PRIMARY |       4 | wfs-test.form.sectid |    1 |
+----+-------------+------------+--------+---------------+---------+---------+----------------------+------+

MySQL 在从 table form 获取数据时没有理由使用索引。因为查询没有任何 WHERE 子句,所以来自 table from 的所有行可能都将包含在最终结果集中。更多,因为没有 ORDER BY 子句,所以行的任何顺序都足够了。这就是为什么 MySQL 直接从 table 获取行,而不参考任何索引。

如果包含 WHERE 条件中涉及的(部分)字段的索引存在(并且这些字段放入正确顺序,是索引中包含的最左边的列)。

在来自 table form 的字段上添加 ORDER BY 子句(没有 WHERE)也可以在从 table form 包含在索引中。它会将类型从 ALL 更改为 index,这意味着它将对索引而不是数据行进行全面扫描以获取所需的数据。虽然这仍然是一次完整扫描,但 full index scan 通常比 full table scan 运行得更快,因为从存储加载和解析的数据较少(索引通常小于 table 数据)。

有关此内容的更多信息,请参见 MySQL documentation

整个 "8.2.1 Optimizing SELECT Statements" 部分值得一读,以更好地理解如何编写更快的查询。