我在密钥date_insert
上分区了大约100亿条记录。
MY_BIG_TABLE
输入:
注意::date_input1 < :date_input2
我想要
IF date_fact < :date_input_1
按date_fact DESC ELSE IF date_fact < :date_input_2
按date_fact ASC ELSE
最新的查询原型应该是:
SELECT date_insert, date_fact, data (
SELECT
date_insert,
date_fact,
CASE
WHEN (date_fact < :date_input_1 AND id= :id) : 2
WHEN (date_fact < :date_input_2 AND id= :id) : 1
ELSE : 0
check,
CASE
WHEN (date_fact < :date_input_1 AND id= :id) : NULL
WHEN (date_fact < :date_input_2 AND id= :id) : data
ELSE : NULL
data
FROM MY_BIG_TABLE
WHERE date_insert > :date_input3
order by check, DECODE(check, 1, date_fact) ASC,
date_fact DESC
) WHERE ROWNUM <2
我需要做这项艰苦的工作,以避免过多访问此表。 要完全重建查询的任何建议更简单,更容易吗?
答案 0 :(得分:4)
你只想找一排。那么,做三个不同的子查询,每个子查询一行,然后选择你想要的那个:
select date_insert, date_fact, data
from (select date_insert, date_fact, data
from ((select date_insert, date_fact, data, 2 as check
from (select date_insert, date_fact,
(CASE WHEN (date_fact < :date_input_1 AND id= :id) then NULL
WHEN (date_fact < :date_input_2 AND id= :id) then data
ELSE NULL
end) as data
from MY_BIG_TABLE
where date_fact < :date_input_1 and date_insert > :date_input3
order by date_fact desc
) t
where rownum = 1
) union all
(select date_insert, date_fact, data, 1 as check
from (select date_insert, date_fact,
(CASE WHEN (date_fact < :date_input_1 AND id= :id) then NULL
WHEN (date_fact < :date_input_2 AND id= :id) then data
ELSE NULL
end) as data
from MY_BIG_TABLE
where date_fact < :date_input_2 and date_insert > :date_input3
order by date_fact asc
) t
where rownum = 1
) union all
(select date_insert, date_fact, data, 0 as check
from (select date_insert, date_fact,
(CASE WHEN (date_fact < :date_input_1 AND id= :id) then NULL
WHEN (date_fact < :date_input_2 AND id= :id) then data
ELSE NULL
end) as data
from MY_BIG_TABLE
where date_insert > :date_input3
order by date_fact desc
) t
where rownum = 1
)
) t
order by check desc
) t
where rownum = 1;
Oracle应该足够聪明,可以使用子查询的索引,因此这可能实际上运行得非常快。