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 并重命名。所以基本上你有一些逻辑上的东西
插入T1_new
select .... 其中 DUP = 1
下降tableT1
将 T1_new 重命名为 T1
这也打开了使用直接路径插入的机会(通过 /*+APPEND */ 提示)。如果您有可用的资源,您也可以使用并行性。
- 将 FLAG1 添加到索引。 将索引更改为
CREATE INDEX T1IDX ON T1 ("A", "B", "C", "D", "FLAG1");
将允许 DELETE 语句像瘦 table 一样使用索引。计划应更改为使用 INDEX FULL SCAN
或 INDEX FAST FULL SCAN
.
- 使用临时撤销。 Oracle 12c 允许将撤销信息存储在临时 table 的 table 空间内,减少了撤销和重做的生成。要启用此功能,运行 类似
ALTER SESSION SET TEMP_UNDO_ENABLED = TRUE;
的命令。 (但要注意首先创建一个新会话。如果您的会话之前使用过临时 table,该命令将默默地失败。)我对您的对象进行的小数据测试仅显示 7% 的性能改进,但它是轻松改变,没有缺点。
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 并重命名。所以基本上你有一些逻辑上的东西
插入T1_new select .... 其中 DUP = 1
下降tableT1
将 T1_new 重命名为 T1
这也打开了使用直接路径插入的机会(通过 /*+APPEND */ 提示)。如果您有可用的资源,您也可以使用并行性。
- 将 FLAG1 添加到索引。 将索引更改为
CREATE INDEX T1IDX ON T1 ("A", "B", "C", "D", "FLAG1");
将允许 DELETE 语句像瘦 table 一样使用索引。计划应更改为使用INDEX FULL SCAN
或INDEX FAST FULL SCAN
. - 使用临时撤销。 Oracle 12c 允许将撤销信息存储在临时 table 的 table 空间内,减少了撤销和重做的生成。要启用此功能,运行 类似
ALTER SESSION SET TEMP_UNDO_ENABLED = TRUE;
的命令。 (但要注意首先创建一个新会话。如果您的会话之前使用过临时 table,该命令将默默地失败。)我对您的对象进行的小数据测试仅显示 7% 的性能改进,但它是轻松改变,没有缺点。