非常小的MySQL表会忽略索引吗?

时间:2018-02-21 19:31:06

标签: mysql mariadb

启用log_queries_not_using_indexes后,我注意到一个查询正在快速填满慢查询日志:

SELECT abc.* FROM abc WHERE abc.id NOT IN ( SELECT DISTINCT abc_id FROM zyx WHERE id = 12345 );

abc非常小,只有3行数据。 zyx相对较大,有超过100,000行数据。

abc.id有一个索引,但当我EXPLAIN查询时,索引不会列在keypossible_keys下。这解释了为什么查询显示在慢速日志中,但我的问题是,为什么它不使用索引?

简而言之,我有两个问题:

  1. 非常小的表会忽略索引吗?我明白为什么,它不会节省太多时间在3行数据上使用索引。
  2. 如果是这样,我怎样才能阻止此查询充斥我的慢查询日志?
  3. 感谢您的时间! :)

    如有需要,请提供其他信息:

    我已经运行了ANALYZE TABLE abc因为我有时会解读这个问题。自从添加索引后我也重新启动了MariaDB。

    更多EXPLAIN:select_type = PRIMARY,table = abc,type = ALL,possible_keys = NULL,key = NULL,key_len = NULL,ref = NULL,rows = 3,Extra = Using where

2 个答案:

答案 0 :(得分:2)

  

非常小的表会忽略索引吗?

是。当可以在单个磁盘访问中读取整个表时,执行单独的磁盘访问以读取索引是没有意义的。

  

如果是这样,我怎样才能阻止此查询充斥我的慢查询日志?

关闭log_queries_not_using_indexes。这是默认情况下不启动的原因之一。

答案 1 :(得分:1)

NOT IN ( SELECT ... )的优化效果非常差,尤其是旧版本。

更改为:

SELECT  abc.*
    FROM  abc
    LEFT JOIN  zyx  ON zyx.abc_id = abc.id
    WHERE  zyx.abc_id IS NULL;
AND  zyx.id = 12345 ;

对于zyx,请INDEX(id, abc_id)INDEX(abc_id, id)

如果zyx.idPRIMARY KEY,那么您的查询没有多大意义 - 为什么要测试单行(12345)?