目录
in 语法为:
select *
from table_name
where col_name in (value1, value2,...);in 操作符允许在 where 子句中规定多个值。
in 查询相当于多个 or 条件的叠加,比较好理解。
in 查询就是先将子查询条件的记录全都查出来。
in 查询的子条件返回结果必须只有一个字段。
exists 语法为:
select *
from table_a a
where exists (select 1 from table_b b where b.id = b.id);exists 对外表用 loop 逐条查询,每次查询都会查看 exists 的条件语句。
当 exists 里的条件语句能够返回记录行时(无论返回多少记录行,只要能返回),条件就为真,返回当前 loop 到的这条记录。
反之如果 exists 里的条件语句不能返回记录行,则当前 loop 到的这条记录被丢弃。
exists 的条件就像一个 bool 条件,当能返回结果集则为 true,不能返回结果集则为 false。
当子查询为 select NULL 时, mysql 仍然认为它是 True。
确定给定的值是否与子查询或列表中的值相匹配。
in 在查询的时候,首先查询子查询的表,然后将内表和外表做一个笛卡尔积,然后按照条件进行筛选。
所以相对内表比较小的时候,in 的速度较快。
指定一个子查询,检测行的存在。
遍历循环外表,检查外表中的记录有没有和内表的的数据一致的。
匹配得上就放入结果集。
in 和 exists 的区别: 如果子查询得出的结果集记录较少,主查询中的表较大且又有索引时应该用 in, 反之如果外层的主查询记录较少,子查询中的表大,又有索引时使用 exists。
其实我们区分 in 和 exists 主要是造成了驱动顺序的改变(这是性能变化的关键),如果是 exists,那么以外层表为驱动表,先被访问,如果是 in ,那么先执行子查询,所以我们会以驱动表的快速返回为目标,那么就会考虑到索引及结果集的关系 ,另外 in 是不对 NULL 进行处理。
in 是把外表和内表作 hash 连接,而 exists 是对外表作 loop 循环,每次 loop 循环再对内表进行查询。一直以来认为 exists 比 in 效率高的说法是不准确的。
如果查询语句使用 not in,那么内外表都进行全表扫描,没有用到索引;
而 not exists 的子查询依然能用到表上的索引。所以无论那个表大,用 not exists 都比not in 要快。
1. 外层查询表小于子查询表,则用 exists,外层查询表大于子查询表,则用 in ,如果外层和子查询表差不多,则爱用哪个用哪个。
2.not exists 比 not in 效率高。
in 的遍历是在内存中遍历。
而 exists 需要查询数据库。
查询数据库所消耗的性能更高,而内存比较快。
参考链接1:在MySQL里,有个和in一样的东东叫做exists,但是它比in更牛叉,你会么?
原文:https://www.cnblogs.com/hider/p/12446035.html