原文:https://dev.mysql.com/doc/refman/5.7/en/table-scan-avoidance.html
8.2.1.19 Avoiding Full Table Scans
在使用EXPLAIN分析一个查询语句时,如果type列的值是“ALL”,那么这个语句就执行了全表扫描。全表扫描经常在下面几种情况下发生:
- 表很小,以至于全表扫描比索引查询更快。通常发生在表数据少于10条且每行数据较短时。
- 在ON或WHERE中没有使用索引列。
- 你在索引列使用了常量值查询,但是MySQL分析(基于索引树)后,发现表中非常多的数据会被匹配到,使用全表扫描会更快。更多信息8.2.1.1, “WHERE Clause Optimization”.
- 如果你使用一个低基数(大量的行使用同一个值)的列上的索引,MySQL会认为使用该索引会扫描大量的行,表扫描可能会更快。
对小表来说,表扫描是合适的,对性能的影响是可以忽略的。对大表来说,使用下面的技术来防止优化器错误的执行表扫描:
- 使用ANALYZE TABLE tbl_name来更新键值分布。查看Section 13.7.2.1, “ANALYZE TABLE Syntax”
- 使用FORCE INDEX来指定执行查询时使用的索引:
SELECT * FROM t1, t2 FORCE INDEX (index_for_column)
WHERE t1.col_name=t2.col_name;
See Section 8.9.4, “Index Hints”.
- 启动 mysqld 时使用参数 –max-seeks-for-key=1000 或者执行 SET max_seeks_for_key=1000 来告诉优化程序,所有的索引都不会导致超过1000次的索引搜索。See Section 5.1.5, “Server System Variables”.