8.2.1.20 避免全 table 扫描

当 MySQL 使用全 table 扫描解析查询时,EXPLAIN的输出在type列中显示ALL。这通常在以下情况下发生:

  • 该 table 是如此之小,以至于执行 table 扫描要比打扰键查找要快得多。对于少于 10 行且行长较短的 table,这是常见的。

  • 索引列的ONWHERE子句没有可用的限制。

  • 您正在将索引列与常量值进行比较,并且 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 节“索引提示”.