我使用减运算符来比较两个表。例如:
select colmn1, ..., column10 from table
minus
select colmn1, ..., column10 from remote_table@db_link;
但是如果表格太大,我会收到以下错误
ORA-01652:无法在表空间TEMP中将临时段扩展128。
还有其他办法吗?
答案 0 :(得分:2)
您可以将数据拆分成碎片并逐个进行比较。但它不会是一个查询。像这样:
declare
diff number := 0;
subdiff number;
piece_size number := 1000;
table_size number;
begin
select count(*)
into table_size
from table;
for i in (select rownum r from dual connect by level <= ceil(table_size/piece_size)) loop
select count(*)
into subdiff
from (select colmn1, ..., column10 from table
where id between (i.r - 1) * piece_size and i.r * piece_size
minus
select colmn1, ..., column10 from remote_table@db_link
where id between (i.r - 1) * piece_size and i.r * piece_size);
diff := diff + subdiff;
end loop;
dbms_output.put_line('Total lines: ' + diff);
end;
在这里,您计算本地表中的行数,然后将其拆分为1000行(变量piece_size
),并逐个比较表,收集{{1}中不同行的总数变量。然后你会看到循环后的总行数
这可能需要很长时间,所以首先你需要找到最大尺寸的块,这不会引起错误。这取决于您的系统,可能是10万行,1 000 000行或任何其他大小
如果您需要自己查看行,而不仅仅是金额,您可以以相同的方式将它们复制到临时表中。
答案 1 :(得分:2)
&#34;如果表太大,我收到以下错误&#34;
您正在执行minus
操作,这需要Oracle对这两个表进行排序。当表很大时,Oracle使用磁盘来保存中间排序结果。这意味着写入临时表空间;如果排序超过临时表空间的容量,则会得到ORA-01652
。
首先,与您的DBA交谈。也许有很多种情况发生,你可能会在更安静的时候有更好的运气。也许他们可以扩展TEMP表空间。或者他们可能只为您的用户提供专用的临时表空间(可能只是为了本练习的目的而站起来 - 这取决于您正在做什么以及为什么)。
&#34;还有其他方式吗?&#34;
这还取决于你正在做什么以及为什么。对于一次性练习,您可以将任务分成多个步骤:
如果公共记录集仍然太大,您可以通过连接所有列并使用ora_hash()
或Oracle的一个加密函数对它们进行散列来创建每个记录的校验和。这将为您提供两个比较小的数据块。
如果这是重复练习,您需要重新考虑您的数据管理策略。也许其中一个表应该是对另一个表的物化视图。
最后,请记住,您必须使用MINUS两次:A minus B
和B minus A
。校验和的一个吸引人之处在于它使这项操作更容易
select t1.id as local_id
, t2.id as remote_id
, case
when t1.id is null then 'not in local'
when t2.id is null then 'not in remote'
else 'existing changed'
end as state
from your_table as t1
full outer join your_table@remote_db t2
on t1.id = t2.id
where t1.id is null
or t2.id is null
or t1.check_sum != t2.check_sum
答案 2 :(得分:0)
尝试使用&#34; NOT IN&#34;代替。
select *
from employees
where (department_id, manager_id) not in
(select department_id, manager_id
from departments ) ;
&#34;减&#34;操作需要排序,这导致从oracle服务器的PGA内存中获取大量内存,如果还不够,则从临时段中获取。 &#34;不在&#34;有时候也会使用排序,但通常不会。
此外,如果您只需要来自表A的数据而没有来自B的数据,并且不需要从结果中排除重复项,那么&#34; NOT IN&#34;是正确的选择。