1

我在 oracle 中有一个非常大的表,其中包含 140+ 百万行。目前,我们每晚对该表进行三次全表扫描,并使用一些结果来填充一个 tmp 表。然后将该 tmp 表变成一个非常大的报告(通常 140K + 行)。

大表称为tasklog,具有以下结构:tasklog_id (number) - PK document_id (number) date_time_in (date) + 一些不相关的行

有数百万个不同的文档 ID,每个 ID 都重复了 1 到几百次,date_time_in 是这个条目被放入数据库的时间。

所有的全表扫描看起来像这样

DECLARE
n_prevdocid     number;

cursor tasks is
   select * 
   from tasklog
   order by document_id, date_time_in DESC;

BEGIN

for tk in tasks
loop
    if n_prevdocid <> tk.document_id then
         -- *code snipped*

    end if;
    n_prevdocid = tk.document_id;
end loop;

END;
/

所以我的问题是:是否有一种快速(ish)的方法来获取具有最新 date_time_in 的行的不同 document_id 列表。这可以大大加快整个过程。或者有人能想出更好的方法来每天检索这些数据吗?

可能相关的事情,这个表只插入了当前日期时间的行。它不是范围分区的,但我看不出这对我有什么帮助。不会更新或删除任何行。每天插入大约 70k - 80k 行。

4

3 回答 3

1

我不认为你会避免至少进行一次全表扫描,因为唯一有效的方法是不同 document_id 与总记录的比率非常小。由于数据的生成和插入方式,document_id 上的聚类将非常差。

怎么样:

create table tmp nologging compress -- or pctfree 0
as
select ...
from   (
  select t.*,
         max(date_time_in) over (partition by document_id) max_date_time_in
  from   tasklog t)
where   date_time_in = max_date_time_in

可能,在创建一次后,您可以通过仅将较新的记录合并到该集合中来优化进一步的刷新。就像是 ...

merge into tmp
using (
  select ...
  from   (
    select t.*,
           max(date_time_in) over (partition by document_id) max_date_time_in
    from   tasklog t
    where  date_time_in > (select max(date_time_in) from tmp))
  where   date_time_in = max_date_time_in)
on ... blah blah
于 2012-12-12T09:25:56.857 回答
0

你有没有尝试过:

select document_id
from tasklog t1
where date_time_in = (select max(date_time_in)
                      from tasklog t2
                      where t1.document_id=t2.document_id)
于 2012-12-12T06:39:22.203 回答
0

你可以这样做:

select document_id , date_time from tasklog group by date_time,document_id order by date_time desc;

通过这个,您可以检索distinct document_id最新的date_time列。

于 2012-12-12T07:08:39.370 回答