1

所以我有这个表包含 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会这样做?"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知道 mysql

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

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

4

1 回答 1

1

问:为什么 MySQL 会这样做?

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

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

A:你可以尝试影响统计信息的收集,所以 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
于 2014-10-31T19:16:18.310 回答