即使索引存在,mysql也会执行全表扫描

时间:2014-10-31 18:42:27

标签: mysql performance indexing full-table-scan

所以我有这个表包含100000行

field1 field2 

现在我刚刚添加了一个新的列field3,而且field3上有一个索引

field1 field2 field3

所以我添加了大约50行包含field3(其他行将field3作为NULL)

所以我做了一个选择

SELECT * FROM table WHERE field3 IN (val1, val2);

对此的解释是相当理智的。它使用field3上的索引,只扫描2行

然而,当我在IN语句中添加更多值

SELECT * FROM table WHERE field3 IN (val1, val2, val3, val4, val5, val6, val7, val8, val9, val10);

最终不使用索引,最终执行整个100000多行的全表扫描。

为什么mysql这样做?我知道来自http://dev.mysql.com/doc/refman/5.1/en/mysql-indexes.html

的mysql "If you need to access most of the rows, it is faster to read sequentially, because this minimizes disk seeks."

但这可能比使用索引获取这10个值

更快

为什么mysql会这样做?如何指示mysql强制它们使用索引而不是执行全表扫描......

1 个答案:

答案 0 :(得分:1)

问:为什么MySQL会这样做?

A:可能MySQL对索引基数的估计与您预期的不同,并且MySQL估计全表扫描比使用索引更有效。 MyISAM和InnoDB都有影响统计的方法。参考:http://dev.mysql.com/doc/refman/5.5/en/myisam-index-statistics.html

问:如何指示MySQL强制他们使用索引?

答:您可以尝试影响统计信息收集,因此MySQL会提供不同的基数。

或者您可以尝试在查询文本中包含索引提示:

SELECT * FROM mytable FORCE INDEX myindex WHERE ...

或者,您可以尝试将查询重写为多个SELECT与UNION ALL集合运算符:

SELECT * FROM mytable WHERE field3 = val1
 UNION ALL
SELECT * FROM mytable WHERE field3 = val2
 UNION ALL
SELECT * FROM mytable WHERE field3 = val3