0

此查询有效,但需要 5000 毫秒。

SELECT 
    SUM(case 
        when ((TRUNC(OPEN_DATE) <= thedate and TRUNC(END_DATE) > thedate) or(TRUNC(OPEN_DATE) <= thedate and END_DATE Is Null)) then 1 
        else 0 
        end) as Open  
From ( 
    select * 
    FROM PROJECT 
    WHERE 
        PROGRAM_NAME = :program   
        AND ACTION_FOR_ORG = :orgName 
    )   
    cross join ( 
        select add_months(last_day(SYSDATE), level-7) as thedate 
        from dual 
        connect by level <= 12  
    )  
GROUP BY thedate
ORDER BY thedate

如果我将子查询复制到自己的表中

create table test_project as  
select * FROM PROJECT WHERE PROGRAM_NAME = :program   
AND ACTION_FOR_ORG = :orgName

然后执行上述查询,但子查询在复制的表上,如下所示:

From ( select * FROM test_project WHERE PROGRAM_NAME = :program   
AND ACTION_FOR_ORG = :orgName ) 

查询需要 10 毫秒

该查询会根据OPEN_DATEEND_DATE

有没有办法重写原始查询以获得最佳性能?

编辑

好的,我创建了第二个表,它是我被允许访问的项目表(井视图)的完整副本。表格复制大约需要 5 秒。使用完整的数据集和我的 sql 查询或来自下面的 Egor,查询速度非常快。视图有问题。尝试使用子查询中的视图吐出解释计划,但权限不足。这是使用视图的完整副本的解释计划

 Plan hash value: 3695211866

 ------------------------------------------------------------------------------------------------
 | Id  | Operation                        | Name        | Rows  | Bytes | Cost (%CPU)|     Time     |
 ------------------------------------------------------------------------------------------------
 |   0 | SELECT STATEMENT                 |             |   637 |  1277K|   163   (2)| 00:00:02 |
 |   1 |  SORT ORDER BY                   |             |   637 |  1277K|   163   (2)| 00:00:02 |
 |   2 |   HASH GROUP BY                  |             |   637 |  1277K|   163   (2)| 00:00:02 |
 |   3 |    MERGE JOIN CARTESIAN          |             |   637 |  1277K|   161   (0)| 00:00:02 |
 |   4 |     VIEW                         |             |     1 |     6 |     2   (0)| 00:00:01 |
 |*  5 |      CONNECT BY WITHOUT FILTERING|             |       |       |              |          |
 |   6 |       FAST DUAL                  |             |     1 |       |     2   (0)| 00:00:01 |
 |   7 |     BUFFER SORT                  |             |   637 |  1273K|   163   (2)| 00:00:02 |
 |*  8 |      TABLE ACCESS FULL           | COMMIT_TEST |   637 |  1273K|   159   (0)| 00:00:02 |

谓词信息(由操作 id 标识):


5 - filter(LEVEL<=12)
8 - filter("PROGRAM_NAME"='program_name' AND "ACTION_FOR_ORG"='action_for_org')

笔记


- dynamic sampling used for this statement (level=2)

使用活动表解释计划 在此处输入图像描述

4

1 回答 1

1
with
   PRJ as (
      select /*+ NO_UNNEST */ 
         trunc(OPEN_DATE) as OPEN_DATE,
         nvl(trunc(END_DATE), sysdate + 1000) as END_DATE
      from
         PROJECT
      where
         PROGRAM_NAME = :program
         and ACTION_FOR_ORG = :orgName
   ),
   DATES as (
      select
         add_months(trunc(last_day(SYSDATE)), level-7) as thedate
      from dual
      connect by level <= 12
   )
SELECT
   thedate,
   sum(case when thedate between open_date and end_date then 1 end) as Open
FROM
   DATES, PRJ
GROUP BY thedate
ORDER BY 1
于 2013-03-04T22:02:12.113 回答