我有一个表Log
,其中有Doc
和OperDate
列,每个列上有两个索引。我想按给定日期沿着按Doc
分区的上一个日期选择所有行
就像
with
Dates as (select trunc(sysdate) ate from dual),
Log as (select 1 Doc, D.ate OperDate from dual, dates D union all
select 1, D.ate-1 from dual, dates D union all
select 1, D.ate-2 from dual, dates D union all
select 2, D.ate from dual, dates D union all
select 2, D.ate-3 from dual, dates D union all
select 3, D.ate-4 from dual, dates D)
select A.Doc, A.OperDate, (select max(B.Operdate) from Log B where B.Doc = A.Doc and B.OperDate < A.OperDate)
from Log A
where A.OperDate = trunc(sysdate) -- parameter
-- result = 2 rows
字符串
这将是对一个表的两次索引访问,另一方面,如果我使用分析函数,我认为我将失去通过索引的访问。是否可以优化此查询?
1条答案
按热度按时间cigdeys31#
不会,您不会因为使用分析函数而丢失索引访问权限。但是,为了将所有行都输入到该函数中而删除
operdate
上的 predicate ,您将失去访问权限,因为您无法猜测前一个日期是多远。假设您的数据量是这样的,在这里使用索引是合适的,在
LOG(DOC,OPERDATE)
上创建一个复合(多列)索引以方便子查询。OPERDATE
上的现有索引本身将由主查询块使用。您在DOC
上的索引没有用,至少对于这个目的是这样。我建议的综合指数将取代它。但是,如果你只有一个月,并且要求一天,并且一天中的行数非常高,或者如果你在Exadata上,你可能最好不使用索引,并以这种方式编写:
字符串
两种方法都试试,看看哪种最适合你。