75、not exists 和 not in 和 exists 区别
not exists() ---不存在
()里面的子查询的只需要 true或者false
应用场景:
取出a表中不存在b表的数据
例子:
a表数据如下
b表数据如下所示:
取出 a表中 a表和b表身份证不相同的数据
SELECT
*
FROM
users
WHERE
NOT EXISTS (
SELECT
1
FROM
users_test where users.id_card = users_test.id_card)
exist 表示的是存在和not exist 相反
使用not in ()
() 括号子查询表示某个字段不属于子查询中内容
SELECT
*
FROM
users
WHERE
id_card not in (
SELECT
id_card
FROM
users_test where users.id_card = users_test.id_card)
小结:
in 是把外表和内表作hash 连接(即将内表和外表做一个笛卡尔积,然后按照条件进行筛选),
exists是对外表作loop循环,每次loop循环再对内表进行查询。使用exists关键字进行查询的时候,首先,我们先查询的不是子查询的内容,而是查我们的主查询的表,然后,根据主表的每一条记录,依次去判断where后面的条件是否成立:
exists 语句中只要返回true or false就可以了,所以可以直接select id或者select 1
实际开发中使用:
如果查询的两个表大小相当,那么用in和exists差别不大。
如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in。
笛卡尔积简介:
了解序偶:序偶就是带顺序的集合,用来表示一些集合表示不了的东西。
比如直角坐标系上,有两个点,(2,3)和(3,2),点的坐标就是序偶,因为它自带顺序,为什么每次一个点都先读x坐标再读y坐标?是因为规定了顺序,才能表示更多的点。坐标系如果用集合来表示坐标,那{2,3},{3,2}就是同一个点了。
笛卡尔积定义:
令A和B是任意两个集合,若序偶的第一个成员是A的元素,第二个成员是B的元素,所有这样的序偶集合,称为集合A和B的笛卡尔乘积或直积,记做A X B
A集合{a1,a2,a3,a4,a5},B集合{b1,b2,b3,b4,b5}
A X B表示笛卡尔积:{<a1,b1>,<a1,b2>,<a1,b3>,<a1,b4>},<a1,b5>,<a2,b1>…<an,bn>}
一共有 n X n的数据
所以笛卡尔积是很大的,在使用连接方式的时候,一定要小表连接大表,减少数据库连接次数,提升性能
小表连接大表
for(20条数据){
for(20万数据){
}
}
只需要连接20次数据库
大表连接小表
for(20万条数据){
for(20数据){
}
}
需要连接20万次,浪费资源了