【问题标题】:Oracle Select vs Insert/Select (11GR2)Oracle 选择与插入/选择 (11GR2)
【发布时间】:2012-07-11 10:38:39
【问题描述】:

所以,我正在编写一个进程,该进程将使用大约 10 个不同的选择来填充一个表。作为该过程的一部分,我收集了一些东西,但是在执行 INSERT/SELECT 时,我有时会遇到一些不一致的行为。当我单独运行选择查询时,我会在 10 秒内得到结果(在我刷新缓冲区缓存和 shared_pool 之后),但是一旦我在插入部分上标记,就需要 10 多分钟......

这是我清理表格后正在做的事情...在插入上添加了“追加”提示,这似乎在本周早些时候有很大帮助,但现在它恢复到比平时更长的时间,但只有当执行插入!!

--// Disable GL_JLOG_DETAILS INDEXES
Execute immediate 'alter index IDX_GLDTL1 unusable';
Execute immediate 'alter index IDX_GLDTL2 unusable';


--// SECTION 1
INSERT /*+ APPEND PARALLEL(6) */ INTO GL_JLOG_DETAILS ( MAT_SECTION    
                                                  ,JLOG_KEY        
                                                  ,SRC_CD          
                                                  ,SRC_KEY         
                                                  ,CASE_KEY        
                                                  ,CASE_MBR_KEY    
                                                  ,UNALLOC_ACCT_CD 
                                                  ,FDRT_KEY        
                                                  ,FDRT_TR_CD      
                                                  ,TR_CD           
                                                  ,TR_REF_NO       
                                                  ,STAT_CD         
                                                  ,FD_DESC_ID      
                                                  ,FD_NO           
                                                  ,FD_TYP_CD       
                                                  ,BKT_NO          
                                                  ,RVSL_CD         
                                                  ,CO_CD           
                                                  ,BEN_RPT_TYP_CD  
                                                  ,DB_CR_CD        
                                                  ,ACCT_NO         
                                                  ,SUB_ACCT_NO     
                                                  ,JRNL_AMT        
                                                  ,TDTL_AMT        
                                                  ,RVSL_ERROR      
                                                  ,RVSL_SAME_DAY   
                                                  ,TDTL_REF_KEY)    
          ---// SECTION 1 //--------
          Select  /*+ USE_NL(TMAP,TMOV,ACCT,SBNT,BNTP,FDRT) */ '1' MAT_SECTION,
           JLOG.JLOG_KEY,
           JLOG.SRC_CD,
           TDTL.TDTL_KEY AS SRC_KEY,
           TDTL.CASE_KEY,
           TDTL.CASE_MBR_KEY,
           TDTL.UNALLOC_ACCT_CD,
           TDTL.FDRT_KEY,
           FDRT.TR_CD FDRT_TR_CD,
           TDTL.TR_CD,
           TDTL.TR_REF_NO,
           TDTL.STAT_CD,
           TDTL.FD_DESC_ID,
           TDTL.FD_NO,
           FDDC.FD_TYP_CD,
           TDTL.BKT_NO,
           JLOG.RVSL_CD,
           BNTP.CO_CD,
           SBNT.BEN_RPT_TYP_CD,
           JLOG.DB_CR_CD,
           ACCT.ACCT_NO,
           ACCT.SUB_ACCT_NO,
           JLOG.JRNL_AMT,
           ABS (TDTL.AMT) AS TDTL_AMT,
           CASE
              WHEN TDTL.PROC_DT < TDTL.RVSL_CYC_DT AND TDTL.ORIG_INBS_KEY IS NULL
              THEN
                 1
              ELSE
                 0
             END  RVSL_ERROR,
           CASE
              WHEN  TDTL.PROC_DT = TDTL.RVSL_CYC_DT  AND NOT TDTL.TR_CD IN ('3002','3004','1501','1502','1503','1504','1505')
              THEN 1
              ELSE 0
           END  RVSL_SAME_DAY,
           TDTL.REF_KEY TDTL_REF_KEY
          from GL_JOURNAL_LOGS JLOG, 
               Transact_Details TDTL, 
               FUND_DESC FDDC, 
               FD_RATES FDRT, 
               BEN_TYPES BNTP, 
               SYS_BEN_TYPES SBNT, 
               LEDGER_ACCOUNTS ACCT, 
               TRANS_MAP_OVRD TMOV, 
               TRANSACTION_MAP TMAP 
           WHERE JLOG.JRNL_CD = '0' 
           AND JLOG.SRC_CD = '2' 
           AND JLOG.MKEY_FD_NUM <> 0 
           AND NVL(JLOG.TMOV_KEY, -1) > 0 
           AND NVL(JLOG.ORIG_SCAT_KEY, 1) = 1 
           AND JLOG.Scat_key = TDTL.SCAT_KEY 
           AND JLOG.TR_CD = TDTL.TR_CD 
           AND JLOG.CASE_KEY = TDTL.CASE_KEY 
           AND JLOG.TR_REF_NO = TDTL.TR_REF_NO 
           AND JLOG.ACCT_KEY = ACCT.ACCT_KEY 
           AND JLOG.TMOV_KEY = TMOV.TMOV_KEY 
           AND NVL(TDTL.ORIG_SCAT_KEY, 1) = 1 
           AND TDTL.STAT_CD <> '4' 
           AND TDTL.FD_DESC_ID = FDDC.FD_DESC_ID 
           AND TDTL.FDRT_KEY = FDRT.FDRT_KEY 
           AND BNTP.BNTP_KEY = FDRT.BNTP_KEY 
           AND BNTP.SBNT_KEY  (+) = SBNT.SBNT_KEY 
           AND TMOV.TMAP_KEY = TMAP.TMAP_KEY 
           AND TMOV.CO_CD = BNTP.CO_CD 
           AND DECODE(FDDC.MKEY_FD_NUM, NULL, TMAP.MKEY_FD_NUM, FDDC.MKEY_FD_NUM) = TMAP.MKEY_FD_NUM;

任何提示/建议将不胜感激!

解释计划

Plan hash value: 4157721082

-----------------------------------------------------------------------------------------------------------
| Id  | Operation                              | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT                       |                  |     1 |   212 |  1596   (1)| 00:00:20 |
|   1 |  LOAD AS SELECT                        | GL_JLOG_DETAILS  |       |       |            |          |
|   2 |   NESTED LOOPS                         |                  |       |       |            |          |
|   3 |    NESTED LOOPS                        |                  |     1 |   212 |  1596   (1)| 00:00:20 |
|   4 |     NESTED LOOPS                       |                  |     1 |   195 |  1595   (1)| 00:00:20 |
|   5 |      NESTED LOOPS                      |                  |     1 |   190 |  1594   (1)| 00:00:20 |
|   6 |       NESTED LOOPS                     |                  |    12 |  2172 |  1582   (1)| 00:00:19 |
|*  7 |        HASH JOIN                       |                  |    12 |  2004 |  1570   (1)| 00:00:19 |
|   8 |         TABLE ACCESS FULL              | FUND_DESC        |   168 |  1176 |     4   (0)| 00:00:01 |
|   9 |         NESTED LOOPS                   |                  |       |       |            |          |
|  10 |          NESTED LOOPS                  |                  |   257 | 41120 |  1566   (1)| 00:00:19 |
|  11 |           NESTED LOOPS                 |                  |   257 | 22359 |   537   (0)| 00:00:07 |
|  12 |            NESTED LOOPS                |                  |   257 | 20817 |   280   (0)| 00:00:04 |
|* 13 |             TABLE ACCESS BY INDEX ROWID| GL_JOURNAL_LOGS  |   257 | 18504 |    23   (0)| 00:00:01 |
|* 14 |              INDEX RANGE SCAN          | IDX_ORIGSCATKEY  |   690 |       |     4   (0)| 00:00:01 |
|  15 |             TABLE ACCESS BY INDEX ROWID| TRANS_MAP_OVRD   |     1 |     9 |     1   (0)| 00:00:01 |
|* 16 |              INDEX UNIQUE SCAN         | TMOV_PK          |     1 |       |     0   (0)| 00:00:01 |
|  17 |            TABLE ACCESS BY INDEX ROWID | TRANSACTION_MAP  |     1 |     6 |     1   (0)| 00:00:01 |
|* 18 |             INDEX UNIQUE SCAN          | TMAP_PK          |     1 |       |     0   (0)| 00:00:01 |
|* 19 |           INDEX RANGE SCAN             | IX_AML8890       |     3 |       |     3   (0)| 00:00:01 |
|* 20 |          TABLE ACCESS BY INDEX ROWID   | TRANSACT_DETAILS |     1 |    73 |     4   (0)| 00:00:01 |
|  21 |        TABLE ACCESS BY INDEX ROWID     | FD_RATES         |     1 |    14 |     1   (0)| 00:00:01 |
|* 22 |         INDEX UNIQUE SCAN              | FDRT_PK          |     1 |       |     0   (0)| 00:00:01 |
|* 23 |       TABLE ACCESS BY INDEX ROWID      | BEN_TYPES        |     1 |     9 |     1   (0)| 00:00:01 |
|* 24 |        INDEX UNIQUE SCAN               | BNTP_PK          |     1 |       |     0   (0)| 00:00:01 |
|  25 |      TABLE ACCESS BY INDEX ROWID       | SYS_BEN_TYPES    |     1 |     5 |     1   (0)| 00:00:01 |
|* 26 |       INDEX UNIQUE SCAN                | SBNT_PK          |     1 |       |     0   (0)| 00:00:01 |
|* 27 |     INDEX UNIQUE SCAN                  | ACCT_PK          |     1 |       |     0   (0)| 00:00:01 |
|  28 |    TABLE ACCESS BY INDEX ROWID         | LEDGER_ACCOUNTS  |     1 |    17 |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------------

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

   7 - access("TDTL"."FD_DESC_ID"="FDDC"."FD_DESC_ID")
       filter("TMAP"."MKEY_FD_NUM"=DECODE(TO_CHAR("FDDC"."MKEY_FD_NUM"),NULL,"TMAP"."MKEY_FD_NUM","
              FDDC"."MKEY_FD_NUM"))
  13 - filter("JLOG"."TMOV_KEY" IS NOT NULL AND "JLOG"."SRC_CD"='2' AND "JLOG"."MKEY_FD_NUM"<>0 
              AND NVL("TMOV_KEY",(-1))>0 AND "JLOG"."JRNL_CD"='0')
  14 - access(NVL("ORIG_SCAT_KEY",1)=1)
  16 - access("JLOG"."TMOV_KEY"="TMOV"."TMOV_KEY")
  18 - access("TMOV"."TMAP_KEY"="TMAP"."TMAP_KEY")
  19 - access("JLOG"."SCAT_KEY"="TDTL"."SCAT_KEY" AND "JLOG"."CASE_KEY"="TDTL"."CASE_KEY")
       filter("TDTL"."FD_DESC_ID" IS NOT NULL AND "TDTL"."STAT_CD"<>'4' AND 
              "JLOG"."CASE_KEY"="TDTL"."CASE_KEY")
  20 - filter("TDTL"."FDRT_KEY" IS NOT NULL AND NVL("TDTL"."ORIG_SCAT_KEY",1)=1 AND 
              "JLOG"."TR_CD"="TDTL"."TR_CD" AND "JLOG"."TR_REF_NO"="TDTL"."TR_REF_NO")
  22 - access("TDTL"."FDRT_KEY"="FDRT"."FDRT_KEY")
  23 - filter("TMOV"."CO_CD"="BNTP"."CO_CD")
  24 - access("BNTP"."BNTP_KEY"="FDRT"."BNTP_KEY")
  26 - access("BNTP"."SBNT_KEY"="SBNT"."SBNT_KEY")
  27 - access("JLOG"."ACCT_KEY"="ACCT"."ACCT_KEY")

【问题讨论】:

  • 您确定查询需要 10 秒吗?如果您使用的是 SQL Developer,它只会显示前 x 条记录(x 通常为 50);因此可能需要 10 秒才能显示前 x 条记录,而不是 yyxx(计数为 >>)记录。我看到你关闭了两个索引,还有吗?是否有任何触发器在表上插入时触发(仅此一项就可以杀死性能)。尝试 CTAS(将表创建为 Select)并查看性能
  • 感谢您的回复!我正在 TOAD 中运行选择。选择时间会波动,但在每次尝试时,我仍然会在 20 秒内得到结果,这会拉出前 500 行,所以按照这个速度,考虑到我只有几千条记录要拉,应该仍然相当快。我在插入时禁用了索引,然后在进程结束时重建。我读到这可能会影响插入的性能,因此使您的索引无法用于插入被认为是“良好做法”......目标表上根本没有触发器或约束。
  • 请向我们展示(整个 INSERT 语句的)执行计划
  • 解释计划添加到原帖
  • 如果查询速度很快但插入速度很慢,那么您可能需要查看插入部分而不是计划。桌面上是否还有其他可能导致争用的活动?表空间是否在不断扩展?您是否在等待重做日志滚动? (检查您的警报日志)如果您只执行几千行,这些类型的事情应该不是问题,但可能会给您另一个思路。

标签: oracle optimization oracle11g query-optimization


【解决方案1】:

“直接路径”加载 a.k.a. /*+ APPEND */ 的几个问题。

首先,它通常不一定更快。它直接路径加载到磁盘 - 绕过缓冲区缓存。在许多情况下(尤其是对于较小的数据集),直接路径加载到磁盘会比传统路径加载到缓存中慢。

其次,DPL 在表的高水位线之上工作,这意味着它不会重复使用空间。因此,除非您每次都TRUNCATE 整个表,否则它可能不一定会更快。

第三,一次只有一个用户/用户可以 DPL 到一张桌子上。这可能会导致并发问题,这里所有的修改都将被串行化(就像串行电路,而不是并行电路)。在直接路径的事务提交之前,不允许插入/更新/删除或合并到该表中。

最后,有问题的表的索引很重要。如果不查看数据,很难说哪种索引是合适的以及在哪些列上是合适的。尝试结合使用本地和全局位图索引,但在选择列时要小心。使索引“不可用”通常不是一个好主意,创建它是有目的的,更改它几乎与其直接利益相冲突。

首先,删除所有提示,尝试建立索引。如果它是一个可重新加载的表,则在每次加载之前将其截断。

【讨论】:

    猜你喜欢
    • 2022-06-16
    • 2011-10-20
    • 2012-09-24
    • 2011-10-02
    • 1970-01-01
    • 1970-01-01
    • 2021-10-22
    • 2019-06-03
    • 2014-02-16
    相关资源
    最近更新 更多