性能调优现有Oracle查询

时间:2013-10-24 16:26:01

标签: sql oracle11g sql-execution-plan

我是Oracle的新手,并且已经完成了改进当前在基于Web的应用程序中运行的一些现有SQL查询的任务。我已经提取了以下查询并在SQL Developer中运行它以查看Explain信息。我对计划表输出不太熟悉,并寻求一些帮助,可以改进查询性能,大约需要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 

1 个答案:

答案 0 :(得分:0)

这似乎是“分页”引起的经典性能问题。但是,我试图调查这个,因为这里提供了SQL和执行计划。 如果您搜索大约12个月左右的大窗口( BETWEEN '2012-09-25' AND '2013-09-25' ),CBO将遵循并依赖所有关键表的FTS。 但是,如果有适当的分区,那可能并不坏。 SQL可以非常快地返回(如果没有在期望的2秒内)。

你最昂贵的SQL操作是No 10&amp; 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已更新):

在'TABLE_A'上

1)全局索引以支持代价高昂的'..GROUP BY': -

  CALF.predecessorlinkclasskey,
  CALF.PredActivityKey,
  CALF.SuccActivityKey

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

表-A: “GKEY”上的分区 “SEGMENTSTARTACDDATE”上的子分区

3)缩小日期范围窗口:我还建议您重新考虑并将日期范围窗口缩小到更现实和最佳的级别(可能是一个月或Qtr) 对于50行,没有必要遍历1247K行。

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

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