Oracle 12c 性能调整 - 删除针对全局临时文件的查询 table

Oracle 12c performance tuning - delete query against a global temp table

Oracle 性能专家,

我的任务是调整一个 sql 的野兽 运行 有时超过 18 小时,具体取决于它试图从全局临时文件中删除的行数 table。在 table 上定义了一个索引,但优化器正在执行散列连接 - 这里是 table 的详细信息和 table -[=15= 的解释计划结果]

    DELETE FROM 
       T1
    WHERE ROWID IN
    (
        SELECT ROWID FROM 
        (
            SELECT 
              ROWID,
              ROW_NUMBER() OVER (PARTITION BY A,B,C,D ORDER BY C,D) DUP
              FROM T1
              WHERE FLAG1 = 0
        )
        WHERE DUP > 1
    );

  COMMIT;

table 定义如下 -

CREATE GLOBAL TEMPORARY TABLE "T1"      
   (    
A   VARCHAR2(50 BYTE), 
B   NUMBER(10,0), 
C   VARCHAR2(20 BYTE), 
D   NUMBER, 
A1  FLOAT(126), 
B1  FLOAT(126), 
C1  FLOAT(126), 
D1  FLOAT(126), 
A2  NUMBER, 
B2  NUMBER, 
C2  FLOAT(126), 
D2  FLOAT(126), 
A3  FLOAT(126), 
B3  FLOAT(126), 
C3  FLOAT(126), 
D3  FLOAT(126), 
A4  FLOAT(126), 
B4  FLOAT(126), 
FLAG1   NUMBER
) ON COMMIT PRESERVE ROWS ;     
CREATE INDEX T1IDX ON T1 ("A", "B", "C", "D") ; 

解释计划结果为-

Query Plan                                 Rows        Rowsource Time
DELETE STATEMENT   Cost = 3936614
DELETE  T1                                              1109
       NESTED LOOPS                         1           1
         VIEW  VW_NSO_1                     220M        0
           SORT UNIQUE                      1           163
             VIEW                           220M        2
               WINDOW SORT                  220M        355
                 TABLE ACCESS FULL T1       220M        94
  TABLE ACCESS BY USER ROWID T1             1           313

同样重要的是,当上述查询 运行s 比平时长。在过去的几周里,我们一直在增加临时 space 以暂时缓解错误。我在这里添加 tablespace 信息 -

  Tablespace Name               SizeinMB        FreeMB
  ----------------              ---------       --------
  T1_Sp1_DATA_TS                 3712           180.88
  T1_PE1_INDEX_TS                1              0.94
  SYSAUX                         1160           60.06
  T1_SYS_BLOB_TS                 525            81.13
  T1_SIF_EXPORT_TS               5              4
  T1_SIF_TS                      1              0.69
  T1_FL1_INDEX_TS                3590           173.06
  Staging_DATA_TS                1436           165.63
  T1_FLR_pf1_TS                  2219           238
  T1_Sp1_dv1_TS                  1004           2.75
  T1_Sp1_pf1_TS                  5868           8.75
  T1_SYS_DATA_TS                 34             3.63
  T1_SYS_el1_TS                  159            11.88
  T1_Sp1_INDEX_TS                5785           309.69
  T1_e1_INDEX_TS                 5              4
  USERS                          66740          21538.06
  T1_FL1_DATA_TS                 1932           95.38
  T1_BLOB_TS                     12415          591.44
  T1_Sp1_Fx1_TS                  3249           215.75
  T1_ST1_INDEX_TS                2              0.94
  T1_SIF_INDEX_TS                2              0.38
  SYSTEM                         405            7.19
  T1_FL1_Fx1_TS                  6475           351.63
  T1_ST1_DATA_TS                 1              0.13
  T1_SA_INDEX_TS                 5              4
  T1_NET_DATA_TS                 13             0.19
  T1_Staging_DATA_TS             872404.9375    176406.69
  T1_FL1_sc1_TS                  4071           254.63
  T1_SA_DATA_TS                  5              4
  T1_NET_BLOB_TS                 26757          1291.38
  T1_NET_INDEX_TS                57             3.63
  T1_SYS_INDEX_TS                33             4.88
  T1_Sp1_ps1_TS                  2129           103.75
  T1_e1_DATA_TS                  5              4
  T1_SA_BLOB_TS                  5              4
  T1_SI1_BLOB_TS                 2              0.25
  T1_PE1_DATA_TS                 1              0.94
  TEMP                           196605.96875   

我想知道调整查询以使其更快 运行 的最佳方法是什么 - 我将尝试强制对删除进行索引提示或 NLJ 提示,看看是否有帮助,但如果你们有更好的想法,我将不胜感激。

这是 Oracle 12c,我们拥有所有全局临时 table 的会话级统计信息。我仍在学习 12c 的一些功能,所以不确定如何得出关于此 table.

的大部分会话级统计信息

谢谢, 布伦登

我会改变方法。与其删除不需要的行,不如编写查询以保留所需的行。将它们写入一个新的 table。然后删除旧的 table 并重命名。所以基本上你有一些逻辑上的东西

  1. 插入T1_new select .... 其中 DUP = 1

  2. 下降tableT1

  3. 将 T1_new 重命名为 T1

这也打开了使用直接路径插入的机会(通过 /*+APPEND */ 提示)。如果您有可用的资源,您也可以使用并行性。

  1. 将 FLAG1 添加到索引。 将索引更改为 CREATE INDEX T1IDX ON T1 ("A", "B", "C", "D", "FLAG1"); 将允许 DELETE 语句像瘦 table 一样使用索引。计划应更改为使用 INDEX FULL SCANINDEX FAST FULL SCAN.
  2. 使用临时撤销。 Oracle 12c 允许将撤销信息存储在临时 table 的 table 空间内,减少了撤销和重做的生成。要启用此功能,运行 类似 ALTER SESSION SET TEMP_UNDO_ENABLED = TRUE; 的命令。 (但要注意首先创建一个新会话。如果您的会话之前使用过临时 table,该命令将默默地失败。)我对您的对象进行的小数据测试仅显示 7% 的性能改进,但它是轻松改变,没有缺点。