对较小的数据集使用分析函数,但表中包含所有数据

问题描述 投票:0回答:1

我有一个Oracle大表(约5000万行)。我需要创建一个报告,该报告仅显示大表的一部分的最后/下一个值。例如,该表如下所示,自2010年以来有会话,但是我只需要介绍发生在2019年的会话,但它们的最后一个值可以是2018年或更早的值。如果我过滤表格以仅接受2019年以来的会议,那么最后的会议也将自2019年以来。我不想在整个表上运行,因为它是非常大的表,并且查询很复杂。这将花费很多时间。该表如下所示:

enter image description here

预期结果应为:enter image description here

有什么想法如何生成它以便使其高效,快速地运行?

sql oracle oracle11g query-performance
1个回答
0
投票

典型查询:

select session_id, client_id, session_date, last_session, next_session
  from (
    select session_id, client_id, session_date, 
           lag (session_date) over (partition by client_id order by session_date) last_session,
           lead(session_date) over (partition by client_id order by session_date) next_session
      from sessions )
  where session_date >= date '2019-01-01' order by session_id;

但是它确实表访问已满。您只能过滤2019年数据,并且仅对需要它的行运行子查询:

with t as (
    select session_id, client_id, session_date,
           lag (session_date) over (partition by client_id 
                                    order by session_date) last_session,
           lead(session_date) over (partition by client_id 
                                    order by session_date) next_session
      from sessions 
      where session_date >= date '2019-01-01')
select session_id, client_id, session_date,
       nvl(last_session, (select max(session_date) 
                            from sessions 
                            where client_id = t.client_id 
                              and session_date < t.session_date)) last_session,
       next_session 
  from t order by session_id;

[dbfiddle demo] >>

我创建了两个索引:

create index idx_sessions_date on sessions(session_date);
create index idx_sessions_client_date on sessions(client_id, session_date);

和计划表看起来很有希望,使用了两个索引:

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 1923279194
--------------------------------------------------------------------------------
| Id  | Operation                      | Name                     | Rows  | Byte
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |                          |     6 |   31
|   1 |  SORT AGGREGATE                |                          |     1 |    2
|   2 |   FIRST ROW                    |                          |     1 |    2
|*  3 |    INDEX RANGE SCAN (MIN/MAX)  | IDX_SESSIONS_CLIENT_DATE |     1 |    2
|   4 |  SORT ORDER BY                 |                          |     6 |   31
|   5 |   VIEW                         |                          |     6 |   31
|   6 |    WINDOW SORT                 |                          |     6 |   21
|   7 |     TABLE ACCESS BY INDEX ROWID| SESSIONS                 |     6 |   21
|*  8 |      INDEX RANGE SCAN          | IDX_SESSIONS_DATE        |     1 |
--------------------------------------------------------------------------------
© www.soinside.com 2019 - 2024. All rights reserved.