ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

测试not in,not exists ,left join 查询两表中不同数据的效率

2021-10-12 14:01:42  阅读:346  来源: 互联网

标签:-------- 两表中 join exists where tb id select ta


测试not in,not exists ,left join 查询两表中不同数据的效率

经常要比较找出两个表中不同的数据,前提当然是两个表的结构一致。
三个方法,做一个详细的验证测试,看看哪一个效果最佳 。

1、测试数据准备:

测试环境,准备两个表A和B,结构一样 ,A的数据比B多一点。
为了能够测试出时间差别,表的数据量要大一点,准备10万的数据。

CREATE TABLE "TA" 
   (	"ID" VARCHAR2(8), 
	"NAME" VARCHAR2(8), 
	"AGE" NUMBER(2,0)
   );
CREATE TABLE "TB" 
   (	"ID" VARCHAR2(8), 
	"NAME" VARCHAR2(8), 
	"AGE" NUMBER(2,0)
   );   

写一个脚本做测试,准备10万数据量:


declare
  -- Local variables here
  i     integer;
  t_sql varchar2(1000);

begin
  i := 0;
  -- Test statements here
  -- 清理测试环境
  t_sql := 'truncate table ta';
  execute immediate t_sql;

  t_sql := 'truncate table tb';
  execute immediate t_sql;

  t_sql := 'drop index idx_ta_id';
  execute immediate t_sql;

  t_sql := 'drop index idx_tb_id';
  execute immediate t_sql;
 --10万数据量
  while i < 100000 loop
    insert into ta
    values
      (dbms_random.string('A', 8), dbms_random.string( 'U', 8), dbms_random.value
      (20, 50));
    i := i + 1;
  end loop;

  commit;

  t_sql := 'insert into tb select * from ta';
  execute immediate t_sql;
  execute immediate 'commit';
  --4条不同数据在A表
  i := 0;
  while i < 4 loop
    insert into ta
    values
      (dbms_random.string('A', 8), dbms_random.string( 'U', 8), dbms_random.value
      (20, 50));
    i := i + 1;
  end loop;

  commit;

end;

2、无索引测试效果

SQL> select * from ta left join tb on ta.id=tb.id  where tb.name is null;

ID       NAME     AGE ID       NAME     AGE
-------- -------- --- -------- -------- ---
BrNJOLld CPJNZIBR  42                   
spZVkdVs PEFNZMGN  34                   
yFyReiDC CEBVYXGJ  27                   
NFRXeOvm WPQKQQZI  41                   

Executed in 0.085 seconds


SQL> select * from ta where not  exists (select 1 from tb where ta.id=tb.id) ;

ID       NAME     AGE
-------- -------- ---
spZVkdVs PEFNZMGN  34
NFRXeOvm WPQKQQZI  41
BrNJOLld CPJNZIBR  42
yFyReiDC CEBVYXGJ  27

Executed in 0.066 seconds


SQL> select * from ta where not  exists (select tb.id from tb where ta.id=tb.id) ;

ID       NAME     AGE
-------- -------- ---
spZVkdVs PEFNZMGN  34
NFRXeOvm WPQKQQZI  41
BrNJOLld CPJNZIBR  42
yFyReiDC CEBVYXGJ  27

Executed in 0.09 seconds


SQL> select * from ta where ta.id not in (select tb.id from tb) ;

ID       NAME     AGE
-------- -------- ---
spZVkdVs PEFNZMGN  34
NFRXeOvm WPQKQQZI  41
BrNJOLld CPJNZIBR  42
yFyReiDC CEBVYXGJ  27

Executed in 0.097 seconds

测试结果:
left join :0.085
not exists :0.066 0.090
not in:0.097
说明:
not exist
通过1伪列,效率更高。
select 1 from 中的1是一常量(可以为任意数值),查到的所有行的值都是它,但从效率上来说,1 > 列名 > * 所有记录,因为不用访问字典表,效率最高。

select * from ta where not exists (select 1 from tb where ta.id=tb.id) ;
用tb.id ,更符合习惯和理解。
select * from ta where not exists (select tb.id from tb where ta.id=tb.id) ;

结论是not exists (1)> left join>not exist(id) >not in

3、有索引测试效果

再看看有索引的效果:

SQL> create index idx_ta_id on ta(id);

Index created


Executed in 0.134 seconds


SQL> create index idx_tb_id on tb(id);

Index created


Executed in 0.139 seconds

再执行四个查询语句:

SQL> select * from ta left join tb on ta.id=tb.id  where tb.name is null;

ID       NAME     AGE ID       NAME     AGE
-------- -------- --- -------- -------- ---
BrNJOLld CPJNZIBR  42                   
spZVkdVs PEFNZMGN  34                   
yFyReiDC CEBVYXGJ  27                   
NFRXeOvm WPQKQQZI  41                   

Executed in 0.116 seconds


SQL> select * from ta where not  exists (select 1 from tb where ta.id=tb.id) ;

ID       NAME     AGE
-------- -------- ---
spZVkdVs PEFNZMGN  34
NFRXeOvm WPQKQQZI  41
BrNJOLld CPJNZIBR  42
yFyReiDC CEBVYXGJ  27

Executed in 0.127 seconds


SQL> select * from ta where not  exists (select tb.id from tb where ta.id=tb.id) ;

ID       NAME     AGE
-------- -------- ---
spZVkdVs PEFNZMGN  34
NFRXeOvm WPQKQQZI  41
BrNJOLld CPJNZIBR  42
yFyReiDC CEBVYXGJ  27

Executed in 0.142 seconds


SQL> select * from ta where ta.id not in (select tb.id from tb) ;

ID       NAME     AGE
-------- -------- ---
spZVkdVs PEFNZMGN  34
NFRXeOvm WPQKQQZI  41
BrNJOLld CPJNZIBR  42
yFyReiDC CEBVYXGJ  27

Executed in 0.148 seconds

测试结果:
left join: 0.116
not exists: 0.127 0.142
not in : 0.148

结论是left join>not exists (1)>not exist(id) >not in

4、结论

在10万的数据量比对效果:
(1)无索引:
not exists (1)> left join>not exist(id) >not in
(2)有索引:
left join>not exists (1)>not exist(id) >not in

在生产环境中,一般都是通过索引字段进行比对,因此选择left join 速度更好。

标签:--------,两表中,join,exists,where,tb,id,select,ta
来源: https://blog.csdn.net/qq_39065491/article/details/120721436

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有