我在oracle中有一个非常大的表,包含1.4亿行。目前,我们每晚在此表上进行三次全表扫描,并使用一些结果来填充tmp表。那个tmp表然后变成了一个非常大的报告(通常是140K +行)。
大表名为tasklog,具有以下结构: tasklog_id(数字) - PK document_id(数字) date_time_in(日期) +一些不相关的行
有数百万个不同的文档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_ids的不同列表。这可以大大加快整个过程。或者,任何人都可以想到每天检索这些数据的更好方法吗?
可能相关的事情,此表只插入了当前日期时间的行。这不是范围分区,但我看不出这对我有什么帮助。没有任何行被更新或删除。每天插入大约70k-80k行。
答案 0 :(得分: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
答案 1 :(得分: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)
答案 2 :(得分:0)
您可以这样做:
select document_id , date_time from tasklog group by date_time,document_id order by date_time desc;
通过这种方式,您可以使用最新的distinct document_id
列检索date_time
。