iniestandroid 发表于 2013-12-26 13:09:07

一条简单SQL大量占用临时表空间

本帖最后由 iniestandroid 于 2013-12-26 15:15 编辑

Solaris10
11.2.0.1
业务用户临时表空间晚上用完42G的临时文件后报错,脚本监控了当时临时段的使用情况<font size="1">USERNAME   USER  SESSION_ADDR          SESSION_NUM SQLADDR                  SQLHASH SQL_ID        TABLESPACE CONTENTS  SEGTYPE         SEGFILE#    SEGBLK#        EXTENTS     BLOCKS   SEGRFNO#
---------- ----- ---------------- ----------- ---------------- ---------- ------------- ---------- --------- --------- ---------- ---------- ---------- ---------- ----------
ARDS           ARDS  0000000848DB7B18        23081 00                        0                TS_ARDS_TE TEMPORARY SORT             1002     153728           1064     136192            1
                                                                                        MP

ARDS           ARDS  000000085CE11BB8        52028 00                        0                TS_ARDS_TE TEMPORARY SORT             1002     314752           1388     177664            1
                                                                                        MP

ARDS           ARDS  0000000848E69920        29914 00                        0                TS_ARDS_TE TEMPORARY SORT             1002     493056           1635     209280            1
                                                                                        MP

ARDS           ARDS  0000000850F97F40         5128 00                        0                TS_ARDS_TE TEMPORARY SORT             1002     700288           2297     294016            1
                                                                                        MP

ARDS           ARDS  000000084912E298        26193 00                        0                TS_ARDS_TE TEMPORARY SORT             1002    1946240           3237     414336            1
                                                                                        MP

ARDS           ARDS  0000000850EE6138        26457 00                        0                TS_ARDS_TE TEMPORARY SORT             1003      61184           4596     588288            2
                                                                                        MP

ARDS           ARDS  0000000854EB84A8        <font color="#ff0000">43184 </font>00                        0                TS_ARDS_TE TEMPORARY SORT             1002    <font color="#ff0000">4174208        </font>  28559    3655552            1
                                                                                        MP</font>
serial#为43184的会话当时占用了4174208个block 差不多32G,找到了这个SQL<font size="1">SELECT </font>order by 是ETL模块自己加上去的,后来把order by改了但是问题还是存在,执行计划:<font size="1">Plan hash value: 596693200

-----------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                             | Name                | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
-----------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                      |                     |       |       |  4547M(100)|          |       |       |
|   1 |  SORT ORDER BY                        |                     |    16G|    12T|  4547M  (1)|999:59:59 |       |       |
|   2 |   CONCATENATION                       |                     |       |       |            |          |       |       |
|   3 |    MERGE JOIN CARTESIAN               |                     |    16G|    12T|   567M  (1)|999:59:59 |       |       |
|   4 |     TABLE ACCESS BY GLOBAL INDEX ROWID| BJ_ZLCLB            |   353K|   281M| 21449   (1)| 00:04:18 | ROWID | ROWID |
|   5 |      INDEX RANGE SCAN                 | IDX_BJ_ZLCLB_06     | 63594 |       |   332   (1)| 00:00:04 |       |       |
|   6 |       TABLE ACCESS BY INDEX ROWID     | WF_SRC_CTL          |     1 |    57 |     1   (0)| 00:00:01 |       |       |
|   7 |        INDEX UNIQUE SCAN              | SYS_C0011770        |     1 |       |     0   (0)|          |       |       |
|   8 |     BUFFER SORT                       |                     | 46647 |   592K|   567M  (1)|999:59:59 |       |       |
|   9 |      TABLE ACCESS FULL                | BJ_ZLCLB_TMP        | 46647 |   592K|  1607   (1)| 00:00:20 |       |       |
|  10 |    HASH JOIN                          |                     | 16782 |    13M| 10782   (1)| 00:02:10 |       |       |
|  11 |     INDEX FAST FULL SCAN              | IDX_BJ_ZLCLB_TMP_06 | 46647 |   592K|    55   (2)| 00:00:01 |       |       |
|  12 |     TABLE ACCESS BY GLOBAL INDEX ROWID| BJ_ZLCLB            | 16782 |    13M| 10726   (1)| 00:02:09 | ROWID | ROWID |
|  13 |      INDEX RANGE SCAN                 | IDX_BJ_ZLCLB_06     | 31797 |       |   167   (1)| 00:00:03 |       |       |
|  14 |       TABLE ACCESS BY INDEX ROWID     | WF_SRC_CTL          |     1 |    57 |     1   (0)| 00:00:01 |       |       |
|  15 |        INDEX UNIQUE SCAN              | SYS_C0011770        |     1 |       |     0   (0)|          |       |       |
|  16 |       TABLE ACCESS BY INDEX ROWID     | WF_SRC_CTL          |     1 |    53 |     1   (0)| 00:00:01 |       |       |
|  17 |        INDEX UNIQUE SCAN              | SYS_C0011770        |     1 |       |     0   (0)|          |       |       |
|  18 |       TABLE ACCESS BY INDEX ROWID     | WF_SRC_CTL          |     1 |    53 |     1   (0)| 00:00:01 |       |       |
|  19 |        INDEX UNIQUE SCAN              | SYS_C0011770        |     1 |       |     0   (0)|          |       |       |
-----------------------------------------------------------------------------------------------------------------------------</font>
这个SQL白天手动执行时间是秒级的,但是晚上15分钟也没跑完,各位大神儿帮忙看看为什么这个SQL会占用这么多的临时段?

iniestandroid 发表于 2013-12-26 13:12:35

SELECT T.ZLLYZH AS ZLLYZH,
       T.ZLFLZH AS ZLFLZH,
       T.ZLFLJC AS ZLFLJC,
       T.ZLDSZH AS ZLDSZH,
       T.ZLDSJC AS ZLDSJC,
       T.ZLYWLB AS ZLYWLB,
       T.ZLYWLM AS ZLYWLM,
       T.ZLJYFX AS ZLJYFX,
       T.ZLJYFM AS ZLJYFM,
       T.ZLSJFS AS ZLSJFS,
       T.ZLSJMS AS ZLSJMS,
       T.ZLDJFS AS ZLDJFS,
       T.ZLDJMS AS ZLDJMS,
       T.ZLSJGR AS ZLSJGR,
       T.ZLDJGR AS ZLDJGR,
       T.ZLSZJE AS ZLSZJE,
       T.ZLDZJE AS ZLDZJE,
       T.ZLSCJG AS ZLSCJG,
       T.ZLDQJG AS ZLDQJG,
       T.ZLMEHJ AS ZLMEHJ,
       T.ZLZQSM AS ZLZQSM,
       T.ZLYWBS AS ZLYWBS,
       T.ZLHGLL AS ZLHGLL,
       T.ZLGYLL AS ZLGYLL,
       T.ZLHTH1 AS ZLHTH1,
       T.ZLHTH2 AS ZLHTH2,
       T.ZLLXZE AS ZLLXZE,
       T.ZLYQTS AS ZLYQTS,
       T.ZLFLBZ AS ZLFLBZ,
       T.ZLDSBZ AS ZLDSBZ,
       T.ZLFBXH AS ZLFBXH,
       T.ZLFBDM AS ZLFBDM,
       T.ZLFBJC AS ZLFBJC,
       T.ZLFBME AS ZLFBME,
       T.ZLFBZJ AS ZLFBZJ,
       T.ZLDBXH AS ZLDBXH,
       T.ZLDBDM AS ZLDBDM,
       T.ZLDBJC AS ZLDBJC,
       T.ZLDBME AS ZLDBME,
       T.ZLDBZJ AS ZLDBZJ,
       T.ZLMEXX AS ZLMEXX,
       T.ZLZTFS AS ZLZTFS,
       T.ZLZCYY AS ZLZCYY,
       T.ZLSYBH AS ZLSYBH,
       T.ZLZXYY AS ZLZXYY,
       T.ZLSYMS AS ZLSYMS,
       T.ZLZTSQ AS ZLZTSQ,
       T.ZLDYHT AS ZLDYHT,
       T.ZLDYZL AS ZLDYZL,
       T.ZLXDQR AS ZLXDQR,
       T.ZLZRZH AS ZLZRZH,
       T.ZLZCZH AS ZLZCZH,
       T.ZLCZY  AS ZLCZY,
       T.ZLFHY  AS ZLFHY,
       T.ZLQRY  AS ZLQRY,
       T.ZLZLLY AS ZLZLLY,
       T.ZLJSSJ AS ZLJSSJ,
       T.ZLFHSJ AS ZLFHSJ,
       T.ZLQRSJ AS ZLQRSJ,
       T.ZLZT   AS ZLZT,
       T.ZLFLQR AS ZLFLQR,
       T.ZLDSQR AS ZLDSQR,
       T.ZLCWCS AS ZLCWCS,
       T.ZLBY1  AS ZLBY1,
       T.ZLBY2  AS ZLBY2,
       T.ZLQLBZ AS ZLQLBZ,
       T.ZLGXSJ AS ZLGXSJ,
       T.ZLFBGD AS ZLFBGD,
       T.ZLSBGD AS ZLSBGD,
       T.S_JZSJ AS S_JZSJ,
       T.S_SCBS AS S_SCBS,
       T.S_YWSJ AS S_YWSJ,
       T.ZLBH   AS ZLBH
  FROM BJ_ZLCLB T, BJ_ZLCLB_TMP T1
WHERE T.ZLBH = T1.ZLBH
   AND (T.ZLSJGR >= (SELECT TO_CHAR(BEGIN_DATE, 'YYYYMMDD')
                       FROM WF_SRC_CTL
                      WHERE FD_NAME = 'mapping_day_opds_ards'
                        AND WF_NAME = 'WF_JYZW_ZL1_DAY_OPAR') AND
       T.ZLSJGR <= (SELECT TO_CHAR(END_DATE, 'YYYYMMDD')
                       FROM WF_SRC_CTL
                      WHERE FD_NAME = 'mapping_day_opds_ards'
                        AND WF_NAME = 'WF_JYZW_ZL1_DAY_OPAR'))
    OR T.ZLSJGR <= (SELECT TO_CHAR(CLEAR_DATE, 'YYYYMMDD')
                      FROM WF_SRC_CTL
                     WHERE FD_NAME = 'mapping_day_opds_ards'
                       AND WF_NAME = 'WF_JYZW_ZL1_DAY_OPAR'
                       AND CLEAR_FLAG = 1
                       AND STATUS = 0)
ORDER BY ZLBH,
          ZLLYZH,
          ZLFLZH,
          ZLFLJC,
          ZLDSZH,
          ZLDSJC,
          ZLYWLB,
          ZLYWLM,
          ZLJYFX,
          ZLJYFM,
          ZLSJFS,
          ZLSJMS,
          ZLDJFS,
          ZLDJMS,
          ZLSJGR,
          ZLDJGR,
          ZLSZJE,
          ZLDZJE,
          ZLSCJG,
          ZLDQJG,
          ZLMEHJ,
          ZLZQSM,
          ZLYWBS,
          ZLHGLL,
          ZLGYLL,
          ZLHTH1,
          ZLHTH2,
          ZLLXZE,
          ZLYQTS,
          ZLFLBZ,
          ZLDSBZ,
          ZLFBXH,
          ZLFBDM,
          ZLFBJC,
          ZLFBME,
          ZLFBZJ,
          ZLDBXH,
          ZLDBDM,
          ZLDBJC,
          ZLDBME,
          ZLDBZJ,
          ZLMEXX,
          ZLZTFS,
          ZLZCYY,
          ZLSYBH,
          ZLZXYY,
          ZLSYMS,
          ZLZTSQ,
          ZLDYHT,
          ZLDYZL,
          ZLXDQR,
          ZLZRZH,
          ZLZCZH,
          ZLCZY,
          ZLFHY,
          ZLQRY,
          ZLZLLY,
          ZLJSSJ,
          ZLFHSJ,
          ZLQRSJ,
          ZLZT,
          ZLFLQR,
          ZLDSQR,
          ZLCWCS,
          ZLBY1,
          ZLBY2,
          ZLQLBZ,
          ZLGXSJ,
          ZLFBGD,
          ZLSBGD,
          S_JZSJ,
          S_SCBS,
          S_YWSJ

iniestandroid 发表于 2013-12-26 13:12:52

SQL> select count(*) from BJ_ZLCLB;

  COUNT(*)
----------
   7112940

SQL> select * from user_ind_columns where table_name='BJ_ZLCLB';

INDEX_NAME                     TABLE_NAME                     COLUMN_NAME  COLUMN_POSITION COLUMN_LENGTH CHAR_LENGTH DESCEND
------------------------------ ------------------------------ ------------ --------------- ------------- ----------- -------
IDX_BJ_ZLCLB_01                BJ_ZLCLB                       ZLBH                       1            12          12 ASC
IDX_BJ_ZLCLB_01                BJ_ZLCLB                       S_YWSJ                     2             7           0 ASC
IDX_BJ_ZLCLB_02                BJ_ZLCLB                       S_YWSJ                     1             7           0 ASC
IDX_BJ_ZLCLB_06                BJ_ZLCLB                       ZLSJGR                     1             8           8 ASC
IDX_BJ_ZLCLB_06                BJ_ZLCLB                       ZLBH                       2            12          12 ASC

SQL> SELECT COUNT(*) FROM BJ_ZLCLB_TMP;

  COUNT(*)
----------
     67040

SQL> select * from user_ind_columns where table_name='BJ_ZLCLB_TMP';

INDEX_NAME                     TABLE_NAME                     COLUMN_NAME  COLUMN_POSITION COLUMN_LENGTH CHAR_LENGTH DESCEND
------------------------------ ------------------------------ ------------ --------------- ------------- ----------- -------
IDX_BJ_ZLCLB_TMP_01            BJ_ZLCLB_TMP                   ZLBH                       1            12          12 ASC
IDX_BJ_ZLCLB_TMP_01            BJ_ZLCLB_TMP                   S_YWSJ                     2             7           0 ASC
IDX_BJ_ZLCLB_TMP_06            BJ_ZLCLB_TMP                   ZLSJGR                     1             8           8 ASC
IDX_BJ_ZLCLB_TMP_06            BJ_ZLCLB_TMP                   ZLBH                       2            12          12 ASC

SQL> SELECT COUNT(*) FROM WF_SRC_CTL;

  COUNT(*)
----------
        97

SQL> select * from user_ind_columns where table_name='WF_SRC_CTL';

INDEX_NAME                     TABLE_NAME                     COLUMN_NAME  COLUMN_POSITION COLUMN_LENGTH CHAR_LENGTH DESCEND
------------------------------ ------------------------------ ------------ --------------- ------------- ----------- -------
SYS_C0011770                   WF_SRC_CTL                     FD_NAME                    1            50          50 ASC
SYS_C0011770                   WF_SRC_CTL                     WF_NAME                    2            50          50 ASC

SQL>

Liu Maclean(刘相兵 发表于 2013-12-26 13:37:55

   SELECT *
    FROM (SELECT '1.v$sql'||'实例号:'||GV$SQL.inst_id source,
                 SQL_ID,
                 plan_hash_value,
                 TO_CHAR (FIRST_LOAD_TIME) begin_time,
                 '在cursor cache中' end_time,
                 executions "No. of exec",
                 (buffer_gets / executions) "LIO/exec",
                 (cpu_time / executions / 1000000) "CPUTIM/exec",
                 (elapsed_time / executions / 1000000) "ETIME/exec",
                 (disk_reads / executions) "PIO/exec",
                 (ROWS_PROCESSED / executions) "ROWs/exec"
            FROM Gv$SQL
           WHERE sql_id = '&A'
          UNION ALL
          SELECT '2.sqltuning set' source,
                 sql_id,
                 plan_hash_value,
                 'JUST SQLSET NO DATE' begin_time,
                 'JUST SQLSET NO DATE' end_time,
                 EXECUTIONS "No. of exec",
                 (buffer_gets / executions) "LIO/exec",
                 (cpu_time / executions / 1000000) "CPUTIM/exec",
                 (elapsed_time / executions / 1000000) "ETIME/exec",
                 (disk_reads / executions) "PIO/exec",
                 (ROWS_PROCESSED / executions) "ROWs/exec"
            FROM dba_sqlset_statements
           WHERE SQL_ID = '&A'
          UNION ALL
          SELECT '3.dba_advisor_sqlstats' source,
                 sql_id,
                 plan_hash_value,
                 'JUST SQLSET NO DATE' begin_time,
                 'JUST SQLSET NO DATE' end_time,
                 EXECUTIONS "No. of exec",
                 (buffer_gets / executions) "LIO/exec",
                 (cpu_time / executions / 1000000) "CPUTIM/exec",
                 (elapsed_time / executions / 1000000) "ETIME/exec",
                 (disk_reads / executions) "PIO/exec",
                 (ROWS_PROCESSED / executions) "ROWs/exec"
            FROM dba_sqlset_statements
           WHERE SQL_ID = '&A'
          UNION ALL
          SELECT DISTINCT
                 '4.dba_hist_sqlstat' || '实例号:' || SQL.INSTANCE_NUMBER
                    source,
                 sql_id,
                 PLAN_HASH_VALUE,
                 TO_CHAR (s.BEGIN_INTERVAL_TIME ,'YYYY-MM-DD hh24:mi:ss') begin_time,
                 TO_CHAR (s.END_INTERVAL_TIME,'YYYY-MM-DD hh24:mi:ss') end_time,
                 SQL.executions_delta,
                 SQL.buffer_gets_delta
                 / DECODE (NVL (SQL.executions_delta, 0),
                           0, 1,
                           SQL.executions_delta)
                    "LIO/exec",
                 (SQL.cpu_time_delta / 1000000)
                 / DECODE (NVL (SQL.executions_delta, 0),
                           0, 1,
                           SQL.executions_delta)
                    "CPUTIM/exec",
                 (SQL.elapsed_time_delta / 1000000)
                 / DECODE (NVL (SQL.executions_delta, 0),
                           0, 1,
                           SQL.executions_delta)
                    "ETIME/exec",
                 SQL.DISK_READS_DELTA
                 / DECODE (NVL (SQL.executions_delta, 0),
                           0, 1,
                           SQL.executions_delta)
                    "PIO/exec",
                 SQL.ROWS_PROCESSED_DELTA
                 / DECODE (NVL (SQL.executions_delta, 0),
                           0, 1,
                           SQL.executions_delta)
                    "ROWs/exec"
            FROM dba_hist_sqlstat SQL, dba_hist_snapshot s
           WHERE     SQL.INSTANCE_NUMBER = s.INSTANCE_NUMBER
                 AND SQL.dbid = (SELECT dbid FROM v$database)
                 AND s.snap_id = SQL.snap_id
                 AND sql_id IN ('&A'))
ORDER BY source, begin_time DESC;运行上面的脚本 并输入SQL_ID 给出结果

iniestandroid 发表于 2013-12-26 14:30:12

Liu Maclean(刘相兵 发表于 2013-12-26 13:37 static/image/common/back.gif
运行上面的脚本 并输入SQL_ID 给出结果

           SOURCE        SQL_ID        PLAN_HASH_VALUE        BEGIN_TIME        END_TIME        No. of exec        LIO/exec        CPUTIM/exec        ETIME/exec        PIO/exec        ROWs/exec
1        1.v$sql实例号:1        08andxfxgpws9        596693200        2013-12-21/02:21:50        在cursor cache中        1        20974        339.14        1000.08319        3795        0
2        4.dba_hist_sqlstat实例号:1        08andxfxgpws9        596693200        2013-12-25 02:00:05        2013-12-25 03:00:19        1        20974        339.14        1000.08319        3795        0
3        4.dba_hist_sqlstat实例号:1        08andxfxgpws9        596693200        2013-12-24 10:01:00        2013-12-24 11:00:03        1        16331        1.64        1.68865        0        66993
4        4.dba_hist_sqlstat实例号:1        08andxfxgpws9        596693200        2013-12-24 02:00:16        2013-12-24 03:00:32        1        8997        275.54        858.940176        90        0
5        4.dba_hist_sqlstat实例号:1        08andxfxgpws9        596693200        2013-12-23 14:00:40        2013-12-23 15:00:44        1        13702        1.72        9.512561        8249        46600
6        4.dba_hist_sqlstat实例号:1        08andxfxgpws9        596693200        2013-12-21 02:00:02        2013-12-21 03:00:16        1        15801        221.42        476.332696        1077        0

Liu Maclean(刘相兵 发表于 2013-12-26 14:39:28

就结果看 执行计划都一样 都是596693200

但执行时间有较大的区别 长的时候是1000秒,短的是1秒

逻辑读 和物理读都不高

Liu Maclean(刘相兵 发表于 2013-12-26 14:45:29

需要ASH数据


select * from DBA_HIST_ACTIVE_SESS_HISTORY where sql_id='08andxfxgpws9';

Derek 发表于 2013-12-26 15:06:37

看以一下sql>@?/rdbms/admin/sqltrpt.sql这个条sql的报告,另外BJ_ZLCLB_TMP这张是不是临时表?

iniestandroid 发表于 2013-12-26 15:16:31

本帖最后由 iniestandroid 于 2013-12-26 15:17 编辑

Liu Maclean(刘相兵 发表于 2013-12-26 14:45 static/image/common/back.gif
需要ASH数据




不知道会不会跟 MERGE JOIN CARTESIAN 有关,这个SQL的ASH已经传附件了,谢谢ML!

附件放1L了

iniestandroid 发表于 2013-12-26 15:19:47

Derek 发表于 2013-12-26 15:06 static/image/common/back.gif
看以一下sql>@?/rdbms/admin/sqltrpt.sql这个条sql的报告,另外BJ_ZLCLB_TMP这张是不是临时表? ...

BJ_ZLCLB_TMP 不是临时表,这张表会每天truncate再insert,不明白既然执行计划没变,白天和晚上执行为什么会有这么大的差别

Liu Maclean(刘相兵 发表于 2013-12-26 15:23:50

每天truncate 是几点?

显然 晚上仍使用哪个执行计划可能有问题

另 你有128g内存 ,ORACLE SGA+PGA 只用了 6.47%

        Begin        End
Host Mem (MB):         131,072.0         131,072.0
SGA use (MB):         7,424.0         7,424.0
PGA use (MB):         1,054.5         1,131.5
% Host Mem used for SGA+PGA:         6.47         6.53


PGA用的太少了

Derek 发表于 2013-12-26 15:36:59

iniestandroid 发表于 2013-12-26 15:19 static/image/common/back.gif
BJ_ZLCLB_TMP 不是临时表,这张表会每天truncate再insert,不明白既然执行计划没变,白天和晚上执行为什 ...

@?/rdbms/admin/awrsqrpt.sql 上面打错了,分别上传这条sql白天和晚上的报告,看看

iniestandroid 发表于 2013-12-26 15:48:12

Liu Maclean(刘相兵 发表于 2013-12-26 15:23 static/image/common/back.gif
每天truncate 是几点?

显然 晚上仍使用哪个执行计划可能有问题


truncate和insert操作就在这个这个SQL之前,数据量基本没有变化
机器上有5个库,总共给了差不多90G内存,这个库给了20g memory_target...

Liu Maclean(刘相兵 发表于 2013-12-26 16:01:23

1、order by 涉及的字段过多了
2、同样的执行计划 在半天合适  但到了晚上就不合适 这说明数据量还是发生了变化
3、没有充分使用PGA

action plan:
考虑优化该SQL
不建议用 memory target
具体观察数据的变化

iniestandroid 发表于 2013-12-26 16:14:27

Liu Maclean(刘相兵 发表于 2013-12-26 16:01 static/image/common/back.gif
1、order by 涉及的字段过多了
2、同样的执行计划 在半天合适  但到了晚上就不合适 这说明数据量还是发生了 ...

好的,我先从这几个方面优化看看效果,非常感谢ML和各位的帮助,TKS!

xteitxu 发表于 2013-12-26 17:11:20

楼主解决完  贴下总结哈   关注中。。。

licharles 发表于 2013-12-27 15:06:16

同关注。

kevinlin.ora 发表于 2013-12-27 15:19:00

一般有较大数据量变化时要重新收集统计信息
页: [1]
查看完整版本: 一条简单SQL大量占用临时表空间