有时候系统出问题就需要查询在一张表立却不在另一个表中的数据记录,这样的方法有很多,这里简单介绍其中4种:
1、方法一(仅适用单个字段):使用 not in ,比较容易理解,缺点是效率低
如:select TableA.ID from TableA where TableA.ID not in (select ID from TableB);
2、方法二(适用多个字段匹配):使用 left join...on... , "B.ID isnull" 表示左连接之后在B.ID 字段为 null的记录。
如:select TableA.ID from TableA left join TableB on TableA.ID=TableB.ID where TableB.ID is null ;
3、方法三(适用多个字段匹配)
如:select * from TableB where (select count(1) as num from TableA where TableA.ID = TableB.ID) = 0;
4、方法四(适用多个字段匹配)
如:select * from TableA where not exists(select 1 from TableB where TableA.ID=TableB.ID)
总结:
方法一:第一种not in 场景使用子查询数据量小的情况。因为我子查询只有15w的数据。但是总表有90w。所以我使用not in的话我使用的是外表的索引所以数据较快。
弊端:子查询里面不能存在null字段。如果有,那么你数据就会不准。这种方式的实际情况其实是和字表做hash连接。
方法二:左连接:left join 或 left outer join
(1)左向外联接的结果集包括 LEFT OUTER 子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值(null)。两表进行关联。数据量为两个表的笛卡尔积。返回左表的全部数据。右边不满足条件的为null。如果左表数据大的话,这样关联数据也不小。所以速度这么慢,属于正常。
方法四:第二种not in 场景使用子查询数据量小的情况。因为我子查询只有15w的数据。但是总表有90w。所以我使用not exists的话我使用的是子表的索引。但是我外表数据太大。所以导致速度变慢。
本质:对外表作loop循环,每次loop循环再对内表进行查询。
有问题可在下方评论留言,或关注“大超小志”微信公众号留言。
留言评论
如需留言或评论,请在微信中打开此页面。