所以我有这个包含100000行的表
field1 field2
现在我刚刚添加了一个新列field3,而且在field3 上有一个索引
field1 field2 field3
所以我添加了大约50行包含字段3(其他行的字段3为NULL)
所以我选择
SELECT * FROM table WHERE field3 IN (val1, val2);
对此的解释相当合理。它使用字段3上的索引,只扫描2行
然而,当我在in语句中添加更多值时
SELECT * FROM table WHERE field3 IN (val1, val2, val3, val4, val5, val6, val7, val8, val9, val10);
这最终不使用索引,并最终对整个100000多行执行完整的表扫描。
mysql为什么要这么做?我知道mysql "If you need to access most of the rows, it is faster to read sequentially, because this minimizes disk seeks."
来自http://dev.mysql.com/doc/refman/5.1/en/mysql-indexes.html
但这不可能比使用索引获取这10个值更快
mysql为什么要这样做,我如何指示mysql强制他们使用索引,而不是执行完整的表扫描。。。
Q:MySQL为什么要这么做?
A:MySQL对索引基数的估计可能与您预期的不同,MySQL估计全表扫描比使用索引更有效。有一些方法可以影响统计数据,包括MyISAM和InnoDB。参考:http://dev.mysql.com/doc/refman/5.5/en/myisam-index-statistics.html
Q:如何指示MySQL强制它们使用索引?
A:您可以尝试影响统计信息的收集,因此MySQL会产生不同的基数。
或者,您可以尝试在查询文本中包含索引提示:
SELECT * FROM mytable FORCE INDEX myindex WHERE ...
或者,您可以尝试将查询重写为多个SELECT并结合UNIONALL集合运算符:
SELECT * FROM mytable WHERE field3 = val1
UNION ALL
SELECT * FROM mytable WHERE field3 = val2
UNION ALL
SELECT * FROM mytable WHERE field3 = val3