查询与IN有什么区别

时间:2015-11-14 08:38:33

标签: mysql sql database optimization

我有两个MySQL表,auto_ptrPost

我使用Account作为后端 API ,并生成以下NodeJS语句:

SQL

代码有效,问题是 SLOW !我尝试使用select `p`.`id` as `post_id` from `Post` as `p` left join `Account` as `a` on `a`.`id` = `p`.`author` where `p`.`id` in ('9', '10', '76', '77', 123) order by `p`.`id` asc 来检查发生了什么,它没有使用 INDEX

explaing0

但是,我注意到 IN 子句与数字和字符串混合在一起,因此我将EXPLAIN更改为123并再次 EXPLAIN ,现在使用 INDEX

explaing1

所以,我的问题是当数字和变量混合在 IN 中时会发生什么?

提前致谢

2 个答案:

答案 0 :(得分:2)

如果你看一下MySQL-Documentation How MySQL uses indexes,你会注意到以下声明:

  

不同列的比较(将字符串列与a。比较   例如,时间或数字列可能会阻止使用索引   如果没有转换,则无法直接比较值。对于给定的   数值列中的值如1,它可能比较等于任何值   字符串列中的值的数量,例如“1”,“1”,“00001”或   '01 .e1' 。这排除了对字符串列的任何索引的使用。

因此,如果您在IN - 语句中混淆数据类型,则可以防止使用索引。

答案 1 :(得分:0)

此查询:

select `p`.`id` as `post_id`
from `Post` as `p` left join
     `Account` as `a` 
     on `a`.`id` = `p`.`author` 
where `p`.`id` in ('9', '10', '76', '77', 123) 
order by `p`.`id` asc;

应该利用Post(id)where子句的索引。它可能会也可能无法使用order by的索引。

有两个原因可以解释为什么不会使用Post(id)上的索引。第一种是类型转换。 in列表由字符串组成。我的猜测是id是一个整数。有时,类型转换可能会妨碍使用索引。您可以通过将逻辑更改为:

来检查是否是这种情况
where p.id in (9, 10, 76, 77, 123) 

第二个原因就是表格太小了。 MySQL在选择执行计划时会考虑基数。对于小型表,全表扫描可以比索引更有效。在这种情况下,MySQL应该始终使用覆盖索引。如果要测试此可能性,请在Posts(id, author)上创建索引。这涵盖了查询,优化器应该首选。