2016-12-08 65 views
2

我在甲骨文11g企業版11.2.0.4.0有效的方式來查詢數據的存在分區表中

我有了每個分區約12M行的表。分區是SnapshotDate

我需要評估最近15天的快照是否有任何數據。

在網上找到最多答案告訴我用Row_Number() Over (Partition By SnapshotDate Order By SnapshotDate``。這是我想出了一個代碼(它僅返回值,到目前爲止的日期,所以我需要一個左與我的日曆表連接,當然):

;With OneDateAllDates As 
(
    /* 
     partition by snapshot date so that numbering starts over again 
     i have to use an order by - it gave me an error without one 
    */ 
    Select SnapshotDate, 1 HasData, Row_Number() Over (Partition By SnapshotDate Order By SnapshotDate) RowNumber 
    From FactTable 
    Where SnapshotDate IN 
    (
    /* any mechanism that gives me the last 10 calendar days will do*/ 
    Select CalendarTimeId 
    From DimCalendar 
    Where CalendarDate Between To_Date ('20161208', 'yyyymmdd') - 15 And To_Date ('20161208', 'yyyymmdd') 
) 
) 
Select * 
From AllDates 
Where RowNumber = 1; 

然而,訂貨12M行超過15天瘋狂地昂貴 - 我排序1.8億行,以獲得15行。這是我期望的輸出:

Date   HasData 
=========== ======= 
12/08/2016 1 
12/07/2016 1 
12/06/2016 0 
12/05/2016 0 
12/04/2016 1 
12/03/2016 0 
12/02/2016 1 
12/01/2016 0  
etc etc 

是否有更有效的方法來編寫這樣的查詢?

+0

什麼是分區間隔? –

+0

每日分區,每天12M行 –

回答

1

我不認爲有一個乾淨的方式來結合分區修剪和Top N報告。下面的代碼是醜陋的和重複的,但它可以很快完成工作。

它讀取最近15個日常分區的每個分區,但rownum = 1使其可以快速讀取。日期可以由一個綁定變量替換,但是數字0到15必須是硬編碼的。如果您需要可變天數,則可以硬編碼數十或數百個子查詢,然後使用另一個綁定變量將其過濾掉。運行數百個子查詢並不理想,但它仍然比閱讀1.8億行快得多。

查詢

select CalendarDate, nvl(has_data, 0) has_data 
from 
(
    --The last 15 days. 
    Select CalendarDate 
    From DimCalendar 
    Where CalendarDate Between To_Date ('20161208', 'yyyymmdd') - 15 And To_Date ('20161208', 'yyyymmdd') 
) last_15_days 
left join 
(
    --The last 15 days of data, if any. 
    select date '2016-12-08' - 0 the_date, 1 has_data from FactTable where SnapshotDate in (Select CalendarDate From DimCalendar Where CalendarDate = date '2016-12-08' - 0) and rownum = 1 union all 
    select date '2016-12-08' - 1 the_date, 1 has_data from FactTable where SnapshotDate in (Select CalendarDate From DimCalendar Where CalendarDate = date '2016-12-08' - 1) and rownum = 1 union all 
    select date '2016-12-08' - 2 the_date, 1 has_data from FactTable where SnapshotDate in (Select CalendarDate From DimCalendar Where CalendarDate = date '2016-12-08' - 2) and rownum = 1 union all 
    select date '2016-12-08' - 3 the_date, 1 has_data from FactTable where SnapshotDate in (Select CalendarDate From DimCalendar Where CalendarDate = date '2016-12-08' - 3) and rownum = 1 union all 
    select date '2016-12-08' - 4 the_date, 1 has_data from FactTable where SnapshotDate in (Select CalendarDate From DimCalendar Where CalendarDate = date '2016-12-08' - 4) and rownum = 1 union all 
    select date '2016-12-08' - 5 the_date, 1 has_data from FactTable where SnapshotDate in (Select CalendarDate From DimCalendar Where CalendarDate = date '2016-12-08' - 5) and rownum = 1 union all 
    select date '2016-12-08' - 6 the_date, 1 has_data from FactTable where SnapshotDate in (Select CalendarDate From DimCalendar Where CalendarDate = date '2016-12-08' - 6) and rownum = 1 union all 
    select date '2016-12-08' - 7 the_date, 1 has_data from FactTable where SnapshotDate in (Select CalendarDate From DimCalendar Where CalendarDate = date '2016-12-08' - 7) and rownum = 1 union all 
    select date '2016-12-08' - 8 the_date, 1 has_data from FactTable where SnapshotDate in (Select CalendarDate From DimCalendar Where CalendarDate = date '2016-12-08' - 8) and rownum = 1 union all 
    select date '2016-12-08' - 9 the_date, 1 has_data from FactTable where SnapshotDate in (Select CalendarDate From DimCalendar Where CalendarDate = date '2016-12-08' - 9) and rownum = 1 union all 
    select date '2016-12-08' - 10 the_date, 1 has_data from FactTable where SnapshotDate in (Select CalendarDate From DimCalendar Where CalendarDate = date '2016-12-08' - 10) and rownum = 1 union all 
    select date '2016-12-08' - 11 the_date, 1 has_data from FactTable where SnapshotDate in (Select CalendarDate From DimCalendar Where CalendarDate = date '2016-12-08' - 11) and rownum = 1 union all 
    select date '2016-12-08' - 12 the_date, 1 has_data from FactTable where SnapshotDate in (Select CalendarDate From DimCalendar Where CalendarDate = date '2016-12-08' - 12) and rownum = 1 union all 
    select date '2016-12-08' - 13 the_date, 1 has_data from FactTable where SnapshotDate in (Select CalendarDate From DimCalendar Where CalendarDate = date '2016-12-08' - 13) and rownum = 1 union all 
    select date '2016-12-08' - 14 the_date, 1 has_data from FactTable where SnapshotDate in (Select CalendarDate From DimCalendar Where CalendarDate = date '2016-12-08' - 14) and rownum = 1 union all 
    select date '2016-12-08' - 15 the_date, 1 has_data from FactTable where SnapshotDate in (Select CalendarDate From DimCalendar Where CalendarDate = date '2016-12-08' - 15) and rownum = 1 
) data_from_last_15_days 
    on last_15_days.CalendarDate = data_from_last_15_days.the_date 
order by CalendarDate desc; 

測試模式

create table FactTable 
(
    id number, 
    SnapshotDate date 
) nologging 
partition by range (SnapshotDate) 
interval (interval '1' day) 
(
    partition p1 values less than (date '2000-01-01') 
); 

create table DimCalendar 
(
    CalendarDate date 
); 

--Add last year into calendar. 
insert into DimCalendar 
select date '2016-01-01' + (level - 1) 
from dual 
connect by level <= 365; 


--Insert 1.2 million rows per day. 
begin 
    for i in 1 .. 15 loop 
     insert /*+ append */ into facttable select level, date '2016-12-01' + i from dual connect by level <= 1200000; 
     commit; 
    end loop; 
end; 
/
相關問題