查询性能下降

时间:2014-01-27 09:41:41

标签: sql performance oracle plsql

我有如下查询:

SELECT col1,col2,col3,col4,col5,unit1,unit2,unit3,unit4,unit5
  FROM (select x.*,
               to_number(substr(it_specs,instr(it_specs,',',1,1)+1,instr(it_specs,',',1,2)-instr(it_specs,',',1,1)-1)) unit1,
               to_number(substr(it_specs,instr(it_specs,',',1,2)+1,instr(it_specs,',',1,3)-instr(it_specs,',',1,2)-1)) unit2,
               to_number(substr(it_specs,instr(it_specs,',',1,3)+1,instr(it_specs,',',1,4)-instr(it_specs,',',1,3)-1)) unit3,
               to_number(substr(it_specs,instr(it_specs,',',1,4)+1,instr(it_specs,',',1,5)-instr(it_specs,',',1,4)-1)) unit4,
               to_number(substr(it_specs,instr(it_specs,',',1,5)+1,instr(it_specs,',',1,6)-instr(it_specs,',',1,5)-1)) unit5
          from (select a.*,
                       (select IT_PKG.IT_SPECS(charges, TRUNC(usrdate), 'N')
                          from dual) AS it_Specs
                  from tabl1 A
                  ORDER BY a.col1, a.col2, a.col3, a.col4, a.col5) x) a,
       tabl2 B
  WHERE A.CA = B.CA
  group by col1, col2, col3, col4, col5,
           unit1, unit2, unit3, unit4, unit5

记录数量tabl1的范围是100到25000.tabl2中的记录数是一千。 函数IT_SPECS涉及两个表。每个都有50万条记录。 这个查询工作正常几个月没有性能问题。从下面的轨迹可以看出:

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.01       0.01          0          2          0           0
Fetch     6177      0.90       1.04        375        761          0       12351
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total     6179      0.92       1.06        375        763          0       12351

但表现无明显下降。

 call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.02       0.03          0          0          0           0
Execute      1      0.02       0.10        239        153          0           0
Fetch      107      5.58      26.54        680      70660          0       10637
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total      109      5.64      26.67        919      70813          0       10637

我的问题为什么我获得高查询值和经过的时间也很高? 获取计数是第二种情况,但它对性能没有影响。

解释计划: enter image description here

执行查询时计划:

Rows (1st) Rows (avg) Rows (max)  Row Source Operation
---------- ---------- ----------  ---------------------------------------------------
     11030      11030      11030  FAST DUAL  (cr=0 pr=0 pw=0 time=9295 us cost=2 size=0 card=1)
     12300      12300      12300  HASH GROUP BY (cr=774 pr=375 pw=375 time=738182 us cost=216 size=2290 card=2)
     12613      12613      12613   HASH JOIN  (cr=774 pr=0 pw=0 time=545344 us cost=215 size=14622795 card=12771)
        13         13         13    VIEW  index$_join$_005 (cr=6 pr=0 pw=0 time=2267 us cost=3 size=104 card=13)
        13         13         13     HASH JOIN  (cr=6 pr=0 pw=0 time=2254 us)
        13         13         13      INDEX FAST FULL SCAN C_TYP_UK1 (cr=3 pr=0 pw=0 time=68 us cost=1 size=104 card=13)(object id 81097)
        13         13         13      INDEX FAST FULL SCAN C_TYP_X1 (cr=3 pr=0 pw=0 time=51 us cost=1 size=104 card=13)(object id 390320)
     12613      12613      12613    VIEW  (cr=768 pr=0 pw=0 time=520833 us cost=211 size=14520627 card=12771)
     12613      12613      12613     TABLE ACCESS FULL tabl1 (cr=752 pr=0 pw=0 time=43361 us cost=211 size=13779909 card=12771)

********************************************************************************

计划何时出现性能问题:

Rows (1st) Rows (avg) Rows (max)  Row Source Operation
---------- ---------- ----------  ---------------------------------------------------
     13676      13676      13676  FAST DUAL  (cr=0 pr=0 pw=0 time=26975 us cost=2 size=0 card=1)
     13754      13754      13754  HASH GROUP BY (cr=109351 pr=1072 pw=435 time=31552012 us cost=273 size=2290 card=2)
     15875      15875      15875   HASH JOIN  (cr=109351 pr=637 pw=0 time=37695338 us cost=271 size=20364970 card=17786)
        13         13         13    VIEW  index$_join$_005 (cr=6 pr=0 pw=0 time=5159 us cost=3 size=104 card=13)
        13         13         13     HASH JOIN  (cr=6 pr=0 pw=0 time=5142 us)
        13         13         13      INDEX FAST FULL SCAN C_TYP_UK1 (cr=3 pr=0 pw=0 time=175 us cost=1 size=104 card=13)(object id 81097)
        13         13         13      INDEX FAST FULL SCAN C_TYP_X1 (cr=3 pr=0 pw=0 time=152 us cost=1 size=104 card=13)(object id 390320)
     15875      15875      15875    VIEW  (cr=109345 pr=637 pw=0 time=37587033 us cost=268 size=20222682 card=17786)
     15875      15875      15875     TABLE ACCESS FULL tabl1 (cr=952 pr=632 pw=0 time=50917 us cost=268 size=19191094 card=17786)

********************************************************************************

此查询在数月内运行良好。实际上我更感兴趣的是知道为什么几个月后性能下降以及为什么我们获得高查询价值?

2 个答案:

答案 0 :(得分:0)

你知道早些时候执行的执行计划吗? 首先,收集相关表的表统计信息。

请勿使用(select IT_PKG.IT_SPECS(charges, TRUNC(usrdate), 'N') from dual) AS it_Specs,只需执行IT_PKG.IT_SPECS(charges, TRUNC(usrdate), 'N') AS it_Specs

<强>更新 此查询现在是否返回所需的结果?

WITH x AS
    (SELECT ca,col1,col2,col3,col4,col5,IT_PKG.IT_SPECS(charges, TRUNC(usrdate), 'N') AS it_Specs
    FROM tabl1)
a AS 
    (SELECT x.*, 
        TO_NUMBER(SUBSTR(it_specs,INSTR(it_specs,',',1,1)+1,INSTR(it_specs,',',1,2)-INSTR(it_specs,',',1,1)-1)) unit
    FROM x)
SELECT a.*, 
    unit AS unit1, unit AS unit2, unit AS unit3, unit AS unit4, unit AS unit5 -- always the same
FROM a
    JOIN tabl2 B ON A.CA = B.CA
GROUP BY col1,col2,col3,col4,col5,unit1,unit2,unit3,unit4,unit5
ORDER BY col1,col2,col3,col4,col5

答案 1 :(得分:0)

我已经看到了Oracle在很多次重复函数调用的一些问题,即使它只是&#39;只是&#39;来自dual的选择。

尝试将查询移至with。请参阅this