1

我是 Oracle 的新手,我的任务是改进当前在基于 Web 的应用程序中运行的一些现有 SQL 查询。我提取了以下查询并在 SQL Developer 中运行它以查看解释信息。我对计划表输出不是很熟悉,并且正在寻求一些帮助以提高查询性能,这需要大约 2 秒才能返回 50 行。

询问:

SELECT PATD.StageName                                                                                     AS StageName,
  100 * (LINKS.NEVENTS - LINKS.NCONTACTS) / (DECODE(LINKS.NEVENTS,0,1,LINKS.NEVENTS))                     AS PERCENTREPEAT, 
  LINKS.NEVENTS                                                                                           AS NEVENTS,
  LINKS.NCONTACTS                                                                                         AS NCONTACTS,
  'STAGE'                                                                                                 AS DETAILLEVEL,
  LATD.LinkClassName                                                                                      AS LINKTYPE,
  PATD.ActivityGroupTxt                                                                                   AS PACTIVITYGROUP,
  SATD.ActivityGroupTxt                                                                                   AS SACTIVITYGROUP
FROM
  (SELECT NEVENTS ,
    NCONTACTS ,
    LINKTYPEKEY ,
    PACTIVITYGROUP ,
    SACTIVITYGROUP
  FROM
    (SELECT SUM (
      CASE
        WHEN CALF.PredActivityKey = -1
        THEN 0
        ELSE 1
      END)                                AS NEVENTS,
      COUNT (DISTINCT CALF.RELATEDID)     AS NCONTACTS,
      CALF.predecessorlinkclasskey        AS LINKTYPEKEY,
      CALF.PredActivityKey                AS PACTIVITYGROUP,
      CALF.SuccActivityKey                AS SACTIVITYGROUP
    FROM
      (SELECT * FROM TABLE_A WHERE GKEY = 4
      ) CALF
    JOIN TABLE_B DDate
    ON (DDate.DateKey=CALF.SegmentStartACDDateKey)
    WHERE CALF.segmentstartacddate BETWEEN TO_DATE('2012-09-25', 'YYYY-MM-DD') AND TO_DATE('2013-09-25', 'YYYY-MM-DD')
    AND DDate.fullDate BETWEEN TO_DATE('2012-09-25', 'YYYY-MM-DD') AND TO_DATE('2013-09-25', 'YYYY-MM-DD')
    GROUP BY  CALF.predecessorlinkclasskey,
              CALF.PredActivityKey,
              CALF.SuccActivityKey
    ORDER BY NEVENTS DESC
    )
  WHERE ROWNUM <= 50
  ) LINKS
JOIN TABLE_C LATD
ON (LATD.linkclasskey=LINKS.LINKTYPEKEY)
JOIN TABLE_D PATD
ON (PATD.cfactivitykey=LINKS.PACTIVITYGROUP)
JOIN TABLE_D SATD
ON (SATD.cfactivitykey=LINKS.SACTIVITYGROUP)

计划表输出:

| Id  | Operation                               | Name                    | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     | Pstart| Pstop |                                                                                                                                                                  
-------------------------------------------------------------------------------------------------------------------------------------------                                                                                                                                                                  
|   0 | SELECT STATEMENT                        |                         |    50 |  4550 |       | 54882   (1)| 00:10:59 |       |       |                                                                                                                                                                  
|*  1 |  HASH JOIN                              |                         |    50 |  4550 |       | 54882   (1)| 00:10:59 |       |       |                                                                                                                                                                  
|*  2 |   HASH JOIN                             |                         |    50 |  3850 |       | 54855   (1)| 00:10:59 |       |       |                                                                                                                                                                  
|   3 |    MERGE JOIN                           |                         |    50 |  2550 |       | 54829   (1)| 00:10:58 |       |       |                                                                                                                                                                  
|   4 |     TABLE ACCESS BY INDEX ROWID         | TABLE_C                 |     3 |    39 |       |     2   (0)| 00:00:01 |       |       |                                                                                                                                                                  
|   5 |      INDEX FULL SCAN                    | PK_TABLE_C              |     3 |       |       |     1   (0)| 00:00:01 |       |       |                                                                                                                                                                  
|*  6 |     SORT JOIN                           |                         |    50 |  1900 |       | 54827   (1)| 00:10:58 |       |       |                                                                                                                                                                  
|   7 |      VIEW                               |                         |    50 |  1900 |       | 54826   (1)| 00:10:58 |       |       |                                                                                                                                                                  
|*  8 |       COUNT STOPKEY                     |                         |       |       |       |            |          |       |       |                                                                                                                                                                  
|   9 |        VIEW                             |                         |  1244K|    45M|       | 54826   (1)| 00:10:58 |       |       |                                                                                                                                                                  
|* 10 |         SORT ORDER BY STOPKEY           |                         |  1244K|    45M|    61M| 54826   (1)| 00:10:58 |       |       |                                                                                                                                                                  
|  11 |          HASH GROUP BY                  |                         |  1244K|    45M|    61M| 54826   (1)| 00:10:58 |       |       |                                                                                                                                                                  
|  12 |           VIEW                          | VW_DAG_0                |  1244K|    45M|       | 30184   (2)| 00:06:03 |       |       |                                                                                                                                                                  
|  13 |            HASH GROUP BY                |                         |  1244K|    56M|    81M| 30184   (2)| 00:06:03 |       |       |                                                                                                                                                                  
|* 14 |             HASH JOIN                   |                         |  1244K|    56M|       | 15278   (2)| 00:03:04 |       |       |                                                                                                                                                                  
|  15 |              TABLE ACCESS BY INDEX ROWID| TABLE_B                 |   367 |  5138 |       |    15   (0)| 00:00:01 |       |       |                                                                                                                                                                  
|* 16 |               INDEX RANGE SCAN          | AKI_TABLE_B             |   367 |       |       |     2   (0)| 00:00:01 |       |       |                                                                                                                                                                  
|  17 |              PARTITION RANGE ITERATOR   |                         |  1247K|    40M|       | 15253   (2)| 00:03:04 |    40 |    92 |                                                                                                                                                                  
|  18 |               PARTITION HASH ALL        |                         |  1247K|    40M|       | 15253   (2)| 00:03:04 |     1 |     3 |                                                                                                                                                                  
|* 19 |                TABLE ACCESS FULL        | TABLE_A                 |  1247K|    40M|       | 15253   (2)| 00:03:04 |   118 |   276 |                                                                                                                                                                  
|  20 |    PARTITION LIST ALL                   |                         | 10183 |   258K|       |    26   (0)| 00:00:01 |     1 |     4 |                                                                                                                                                                  
|  21 |     TABLE ACCESS FULL                   | TABLE_D                 | 10183 |   258K|       |    26   (0)| 00:00:01 |     1 |     4 |                                                                                                                                                                  
|  22 |   PARTITION LIST ALL                    |                         | 10183 |   139K|       |    26   (0)| 00:00:01 |     1 |     4 |                                                                                                                                                                  
|  23 |    TABLE ACCESS FULL                    | TABLE_D                 | 10183 |   139K|       |    26   (0)| 00:00:01 |     1 |     4 |                                                                                                                                                                  
-------------------------------------------------------------------------------------------------------------------------------------------                                                                                                                                                                  

Predicate Information (identified by operation id):                                                                                                                                                                                                                                                          
---------------------------------------------------                                                                                                                                                                                                                                                          

   1 - access("SATD"."cfactivitykey"="LINKS"."SACTIVITYGROUP")                                                                                                                                                                                                                               
   2 - access("PATD"."cfactivitykey"="LINKS"."PACTIVITYGROUP")                                                                                                                                                                                                                               
   6 - access("LATD"."LINKCLASSKEY"="LINKS"."LINKTYPEKEY")                                                                                                                                                                                                                                              
       filter("LATD"."LINKCLASSKEY"="LINKS"."LINKTYPEKEY")                                                                                                                                                                                                                                              
   8 - filter(ROWNUM<=50)                                                                                                                                                                                                                                                                                    
  10 - filter(ROWNUM<=50)                                                                                                                                                                                                                                                                                    
  14 - access("DDATE"."DATEKEY"="TABLE_A"."SEGMENTSTARTACDDATEKEY")                                                                                                                                                                                                                                  
  16 - access("DDATE"."FULLDATE">=TO_DATE(' 2012-09-25 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "DDATE"."FULLDATE"<=TO_DATE('                                                                                                                                                                                
              2013-09-25 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))                                                                                                                                                                                                                                               
  19 - filter("GKEY"=4 AND "TABLE_A"."SEGMENTSTARTACDDATE">=TO_DATE(' 2012-09-25 00:00:00', 'syyyy-mm-dd hh24:mi:ss')                                                                                                                                                                            
              AND "TABLE_A"."SEGMENTSTARTACDDATE"<=TO_DATE(' 2013-09-25 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))                                                                                                                                                                                        

Note                                                                                                                                                                                                                                                                                                         
-----                                                                                                                                                                                                                                                                                                        
   - automatic DOP: skipped because of IO calibrate statistics are missing                                                                                                                                                                                                                                   

 49 rows selected 
4

1 回答 1

0

这似乎是由“分页”引起的经典性能问题。但是,我很想研究一下,因为这里提供了 SQL 和执行计划。如果您搜索 12 个月左右的大窗口 ( BETWEEN '2012-09-25' AND '2013-09-25'),CBO 将遵循并在所有关键表上依赖 FTS。但是,如果有适当的分区,那可能不会那么糟糕。SQL 可以很快返回(如果不是在所需的 2 秒内)。

您最昂贵的 SQL 操作是计划输出的第 10 和第 13 项(SORT ORDER 和 GROUP BY)。

|* 10 |         SORT ORDER BY STOPKEY           |                         |  1244K|    45M|    61M| 54826   (1)| 00:10:58 |       |       |                                                                                                                                                                  
|  11 |          HASH GROUP BY                  |                         |  1244K|    45M|    61M| 54826   (1)| 00:10:58 |       |       |                                                                                                                                                                  
|  12 |           VIEW                          | VW_DAG_0                |  1244K|    45M|       | 30184   (2)| 00:06:03 |       |       |                                                                                                                                                                  
|  13 |            HASH GROUP BY                |                         |  1244K|    56M|    81M| 30184   (2)| 00:06:03 |       |       |                                                                                                                                                                  

因此,我会推荐以下内容(基于解释计划并假设 STATS 已更新):

1) 'TABLE_A' 上的全球索引以支持成本高昂的 '..GROUP BY':-

  CALF.predecessorlinkclasskey,
  CALF.PredActivityKey,
  CALF.SuccActivityKey

2)重新访问分区:重新组织表(至少是最大的TABLE_A)上的分区(也可能是子分区)以包括以下内容:

Table_A:“SEGMENTSTARTACDDATE”上“GKEY”子分区上的分区

3)减少日期范围窗口:我还建议您重新考虑并将日期范围窗口减少到更现实和最佳的水平(可能是一个月或一个季度)手头有50行遍历1247K行没有意义.

4) 使用 GTT 来停放临时输出(您可以尝试使用它作为最后的手段。但是,这将需要代码重构/ SQL 拆分等)

您可以尝试所有或其中一些选项。确保您的统计信息(表/索引)是 up-to-update

于 2014-01-27T18:44:23.613 回答