简体   繁体   English

很小的MySQL表会忽略索引吗?

[英]Do very small MySQL tables ignore indexes?

After turning on log_queries_not_using_indexes , I noticed that one query was rapidly filling up the slow query log: 在打开log_queries_not_using_indexes ,我注意到一个查询正在迅速填充慢速查询日志:

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

abc is very small, just 3 rows of data. abc很小,只有3行数据。 zyx is relatively large with over 100,000 rows of data. zyx相对较大,有超过100,000行数据。

abc.id has an index, but when I EXPLAIN the query, the index isn't listed under either key nor possible_keys . abc.id有索引,但是当我EXPLAIN查询,指数也不会被列在key也不possible_keys This explains why the query is showing in the slow log, but my question is, why isn't it using the index? 这解释了为什么查询显示在慢速日志中,但是我的问题是,为什么不使用索引?

In short, I have two questions: 简而言之,我有两个问题:

  1. Do very small tables ignore indexes? 很小的表会忽略索引吗? I could see why, it doesn't save much time to use an index on 3 rows of data. 我可以理解为什么,在3行数据上使用索引并不会节省很多时间。
  2. If so, how can I prevent this query from flooding my slow query log? 如果是这样,如何防止该查询泛滥我的慢查询日志?

Thank you for your time! 感谢您的时间! :) :)

Additional information, if needed: 其他信息(如果需要):

I have run ANALYZE TABLE abc as I've read sometimes fixes the issue. 我已经运行过ANALYZE TABLE abc因为我阅读过有时可以解决该问题。 I have also restarted MariaDB since adding the index. 自添加索引以来,我还重新启动了MariaDB。

More of the EXPLAIN : select_type=PRIMARY, table=abc, type=ALL, possible_keys=NULL, key=NULL, key_len=NULL, ref=NULL, rows=3, Extra=Using where 多个的EXPLAIN :SELECT_TYPE = PRIMARY,表= ABC,类型= ALL,possible_keys = NULL,键= NULL,key_len = NULL,REF = NULL,行= 3,备用=使用其中

Do very small tables ignore indexes? 很小的表会忽略索引吗?

Yes. 是。 When the entire table can be read in a single disk access, there's no point in performing a separate disk access to read the index. 当可以通过单个磁盘访问读取整个表时,执行单独的磁盘访问以读取索引毫无意义。

If so, how can I prevent this query from flooding my slow query log? 如果是这样,如何防止该查询泛滥我的慢查询日志?

Turn off log_queries_not_using_indexes . 关闭log_queries_not_using_indexes This is one of the reasons why it isn't on by default. 这是默认情况下不启用它的原因之一。

NOT IN ( SELECT ... ) is very poorly optimized, especially in older versions. NOT IN ( SELECT ... )优化非常差,尤其是在旧版本中。

Change to this: 更改为此:

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

For zyx, have either INDEX(id, abc_id) or INDEX(abc_id, id) 对于zyx,具有INDEX(id, abc_id)INDEX(abc_id, id)

If zyx.id is the PRIMARY KEY , your query does not make much sense -- why test for a single row (12345)? 如果zyx.idPRIMARY KEY ,那么您的查询就没有多大意义了-为什么要测试一行(12345)?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM