MySQL 8.3 Release Notes
从 EXPLAIN
的输出中可以看到 ALL
在 type
列中,当 MySQL 使用全表扫描来解析查询时。这通常在以下情况下发生:
-
表非常小,以至于执行表扫描比使用键查找更快。这通常发生在少于 10 行且行长度较短的表中。
-
在
ON
或WHERE
子句中没有可用的限制条件用于索引列。 -
您正在比较索引列与常量值,并且 MySQL 已经计算出(基于索引树)常量涵盖了表的太大一部分,因此表扫描将更快。请参阅 第 10.2.1.1 节,“WHERE 子句优化”。
-
您正在通过另一个列使用低基数(许多行匹配键值)的键。在这种情况下,MySQL 假设使用键可能需要许多键查找,因此表扫描将更快。
对于小表,表扫描通常是适当的,并且性能影响可以忽略不计。对于大表,尝试以下技术来避免优化器错误地选择表扫描:
-
使用
ANALYZE TABLE
更新扫描表的键分布。请参阅 第 15.7.3.1 节,“ANALYZE TABLE 语句”。tbl_name
-
使用
FORCE INDEX
对扫描表,告诉 MySQL 表扫描非常昂贵,相比使用给定的索引:SELECT * FROM t1, t2 FORCE INDEX (index_for_column) WHERE t1.col_name=t2.col_name;
请参阅 第 10.9.4 节,“索引提示”。
-
使用 mysqld 选项
--max-seeks-for-key=1000
或使用SET max_seeks_for_key=1000
告诉优化器,假设没有键扫描会导致超过 1,000 次键查找。请参阅 第 7.1.8 节,“服务器系统变量”。