8.2.1.20 避免全 table 扫描
当 MySQL 使用全 table 扫描解析查询时,EXPLAIN的输出在type
列中显示ALL。这通常在以下情况下发生:
-
该 table 是如此之小,以至于执行 table 扫描要比打扰键查找要快得多。对于少于 10 行且行长较短的 table,这是常见的。
-
索引列的
ON
或WHERE
子句没有可用的限制。 -
您正在将索引列与常量值进行比较,并且 MySQL 已计算(基于索引树)(常量覆盖了 table 的很大一部分)并且 table 扫描会更快。参见第 8.2.1.1 节“ WHERE 子句优化”。
-
您正在通过另一列使用基数低的键(许多行与键值匹配)。在这种情况下,MySQL 假定通过使用键,它可能会执行许多键查找,并且 table 扫描会更快。
对于小型 table,table 扫描通常是适当的,并且对性能的影响可以忽略不计。对于大型 table,请尝试以下技术,以避免优化器错误地选择 table 扫描:
-
使用
ANALYZE TABLE tbl_name
更新扫描 table 的密钥分布。参见第 13.7.2.1 节“ ANALYZE TABLE 语句”。 -
对被扫描的 table 使用
FORCE INDEX
来告诉 MySQL 与使用给定索引相比,table 扫描非常昂贵:
SELECT * FROM t1, t2 FORCE INDEX (index_for_column)
WHERE t1.col_name=t2.col_name;
See 第 8.9.4 节“索引提示”.
- 使用--max-seeks-for-key=1000选项以mysqld开头,或使用
SET max_seeks_for_key=1000
告诉优化器假定没有键扫描会导致超过 1000 个键查找。参见第 5.1.7 节“服务器系统变量”。