我们有一个大约75M行的Oracle 11g表。一列称为DOKUMENTUMID,具有或多或少的唯一值,除了几千个重复行。由于遗留软件,我们无法在此字段上添加唯一约束。
但是,现在我们可以添加一个唯一的索引,但要实现这一点,我们必须先清理当前的重复项。为此,我们必须执行SQL无法提供的其他复杂操作。 (文件系统更改/调用API方法等...)
我们有一个标准的Java架构,可以很好地完成这类任务。此Java EE应用程序具有由调度程序调用的单例类。该单例从数据库中获取下一个任务并将其放入JMS队列中。许多消息驱动的bean正在侦听这些消息并正在执行任务。
我正在寻找一种从表中选择副本并将其放入JMS队列的快速方法。目前我的SQL语句如下。
select
inner_select.DOKUMENTUMID from (
select
inner_d.DOKUMENTUMID,
count(*) CNT
from
DOKUMENTUM inner_d
group by
inner_d.DOKUMENTUMID
having
count(*) > 1
) inner_select
where
rownum = 1
order by
inner_select.DOKUMENTUMID desc,
inner_select.CNT desc;
它在大约20秒内运行,这有点太慢了。我认为Oracle在70M +文档上运行全表扫描是不必要的,因为这次我们只需要一个组。
计划B是不经常运行调度方法并立即向队列添加多条消息,但我担心这可能会导致系统负载不均匀。