两张大表对比找出差集

text_android 发布于 2013/07/29 20:05
阅读 1K+
收藏 0

我目前有两张大表 A表 字段( name,obj,operate1,operatetime)

                       B表 字段(name,obj,operate2,operatetime)

两张表的关系   A.name = b.name and a.obj = b.obj

A表中operatetime 会比b表中的operatetime 晚1-10分钟

我现在需要找出 在A表中存在,并且A表operatetime 1-10分钟内 B表没有生成指定记录的信息

目前 A表和B表都有千万级别的记录(oracle数据库)。

请问,我应该如何找出两张表的差集,使用JAVA处理如果数据量小我可以用两层循环进行对比,但是数据量太大我应该使用什么方法呢?

假如使用oracle自身的minus求差集 A表的operatetime要比B表的operatetime晚1-10分钟这里如何处理呢?

 

 

以下是问题补充:

@text_android:这样的大数据,使用java应该如何实现呢?我能想到的是 先对比两个list 找出相同的 然后在用得到的结果和第一个相减得到随后的结果集,但是数据量太大了啊,用这样的方法outofMemory了啊,还有其他实现方法吗,求解 (2013/07/30 17:09)
加载中
0
IdleMan
IdleMan

引用来自“铂金胖子”的答案

效率不高,你试试。如果b.name是索引,或许能快点

select * from a where exists ( select 'x' from b where b.name = a.name and b.operatetime >= a.operatetime -10分钟 and b.operatetime <= a.operatetime-1分钟 )

差了 a.obj =b.a.obj 

SELECT *
  FROM A
 WHERE EXISTS (SELECT NULL
          FROM B
         WHERE B.NAME = A.NAME
           AND A.OBJ = B.A.OBJ
           AND B.OPERATETIME >= A.OPERATETIME - 10分钟
           AND B.OPERATETIME <= A.OPERATETIME - 1分钟);

如果返回记录很多,加了索引也没用,否则加索引性能会显著提高。实在嫌慢可以考虑加个并行hint

IdleMan
IdleMan
当然 not in和not exists对null的处理还是有区别的
IdleMan
IdleMan
回复 @text_android : 在oracle没有exists和in的区别,因为是基于CBO优化器。具体快慢要看数据的分步情况、返回数据的多少来定
t
text_android
千万级别的两张表,用exists多长时间能出结果?我这是个虚拟机上的oracle,测试不出来
铂金胖子
铂金胖子
千万级别的两个表查询,我经常这么干,要不 exists 要不 not in,指考虑结果,不考虑效率。主要用到存储,还是能出结果的。
0
中山野鬼
中山野鬼
oracle的不会,其他方案想听,我可以提提意见。
中山野鬼
中山野鬼
回复 @text_android : 按项独立成表,然后独立用数据计算代码做算法。当然我说的比较空,对于基于oracle的基本没有实用价值。
t
text_android
您好,请问其他方案能指点一下吗?
0
铂金胖子
铂金胖子

效率不高,你试试。如果b.name是索引,或许能快点

select * from a where exists ( select 'x' from b where b.name = a.name and b.operatetime >= a.operatetime -10分钟 and b.operatetime <= a.operatetime-1分钟 )

0
泡不烂的凉粉
泡不烂的凉粉
我理解能力确实差了些, 我没理解楼主想获取表A信息还是表B信息,因为提到

"在A表中存在,并且A表operatetime 1-10分钟内 B表没有生成指定记录的信息"

其实我更愿意理解成, A是登录信息表. B是行为记录表. 
需要搜索 登录信息表A信息内容, 条件是 登录时间+1分钟至+10分钟 时间段 行为记录表B 中无行为记录.

如果按照这样的理解 语句应该是 SELECT * FROM A WHERE NOT EXISTS (SELECT * FROM B WHERE A.name=B.name AND A.obj=B.obj AND (B.operatetime -A.operatetime)>1分钟 AND B.operatetime-A.operatetime<10分钟  

0
t
text_android
如果这种情况,使用java处理如何实现呢?
0
R-Lu
R-Lu

可不可以这样,你先查出B表中最新时间,之后作为条件去判断A表中数据,这样就不会产生循环嘛.

N + N次查询能搞定的.

感觉还是在数据查询上解决问题,你看怎样.大数据可以考虑分表,这样就是先求出每张表里面最新,再比较他们谁最新.

0
芝麻酱拌饭
芝麻酱拌饭

为其中一张表A建张hash表,复杂度O(An),如果内存不够用的话可以用索引来建可扩hash。然后用另外一张表B的每个元素去查表,复杂度O(Bn)。最终复杂度是O(An)+O(Bn)。当然都是理想情况,不过一定比两个循环快很多了。

0
黄龍
黄龍

java嘛~

1.先group by name,obj

2.针对一个主键(name,obj) 查找两张表的数据,产生两个list

3.比较两个list

4.循环2、3

5.如果还会oom,建议你再缩小范围

返回顶部
顶部