【问题标题】:mysql performs full table scan even though index exists即使索引存在,mysql也会执行全表扫描
【发布时间】:2014-10-31 18:42:26
【问题描述】:

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

【问题讨论】:

标签: mysql performance indexing full-table-scan


【解决方案1】:

问: MySQL 为什么要这样做?

答: 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 ...

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

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

【讨论】:

    猜你喜欢
    • 2010-12-18
    • 2017-06-24
    • 1970-01-01
    • 1970-01-01
    • 2016-11-24
    • 1970-01-01
    • 1970-01-01
    • 2020-01-10
    • 2021-09-04
    相关资源
    最近更新 更多