所以我有这个表包含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强制它们使用索引而不是执行全表扫描......
答案 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