一、演示用的表
为了演示二者的区别,先建立两张表 user 表和 order 表
二、in 的执行情况
in在查询的时候,首先查询子查询的表,然后将内表和外表做一个笛卡尔积,然后按照条件进行筛选。所以相对内表比较小的时候,in的速度较快。
sql 和 执行结果
SELECT
*
FROM
`user`
WHERE
`user`.id IN (
SELECT
`order`.user_id
FROM
`order`
)
执行流程
1、查询子查询
SELECT
`order`.user_id
FROM
`order`
2、此时,将查询到的结果和原有的user表做一个笛卡尔积,结果如下:
SELECT
u.id,
u.username,
u.birthday,
u.sex,
u.address,
o.user_id
FROM
`user` u
INNER JOIN (
SELECT
`order`.user_id
FROM
`order`
) o
3、此时,再根据我们的user.id IN order.user_id的条件,将结果进行筛选(既比较id列和user_id 列的值是否相等,将不相等的删除)。最后,得到两条符合条件的数据。
SELECT
u.id,
u.username,
u.birthday,
u.sex,
u.address,
o.user_id
FROM
`user` u
INNER JOIN (
SELECT
`order`.user_id
FROM
`order`
) o on u.id = o.user_id
三、exist
sql 和执行结果
SELECT
`user`.*
FROM
`user`
WHERE
EXISTS (
SELECT
`order`.user_id
FROM
`order`
WHERE
`user`.id = `order`.user_id
)
执行流程
1、使用exists关键字进行查询的时候,首先,我们先查询的不是子查询的内容,而是查我们的主查询的表
SELECT `user`.* FROM `user`
2、然后,根据表的每一条记录,执行以下语句,依次去判断where后面的条件是否成立:
EXISTS (
SELECT
`order`.user_id
FROM
`order`
WHERE
`user`.id = `order`.user_id
)
如果返回的是true的话,则该行结果保留,如果返回的是false的话,则删除该行,最后将得到的结果返回。
四、in 和 exists的区别
-
in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询
-
如果子查询得出的结果集记录较少,主查询中的表较大且又有索引时应该用in;反之如果外层的主查询记录较少,子查询中的表大,又有索引时使用exists。