【问题标题】:Oracle 11g - How to optimize slow parallel insert select?Oracle 11g - 如何优化慢速并行插入选择?
【发布时间】:2013-12-01 14:13:39
【问题描述】:

我们想加快下面并行插入语句的运行。我们预计插入大约 80M 条记录,大约需要 2 小时才能完成。

INSERT /*+ PARALLEL(STAGING_EX,16) APPEND NOLOGGING */ INTO STAGING_EX (ID, TRAN_DT, 
RECON_DT_START, RECON_DT_END, RECON_CONFIG_ID, RECON_PM_ID) 
SELECT /*+PARALLEL(PM,16) */ SEQ_RESULT_ID.nextval, sysdate, sysdate, sysdate, 
'8a038312403e859201405245eed00c42', T1.ID FROM PM T1 WHERE STATUS = 1 and not 
exists(select 1 from RESULT where T1.ID = RECON_PM_ID and CREATE_DT >= sysdate - 60) and 
UPLOAD_DT >= sysdate - 1 and (FUND_SRC_TYPE = :1) 

我们认为缓存不存在列的结果会加快插入速度。我们如何执行缓存?有什么想法可以加快插入速度吗?

有关 Enterprise Manager 的计划统计信息,请参阅下文。我们还注意到这些语句没有并行运行。这正常吗?

编辑:顺便说一句,序列已经缓存到 1M

【问题讨论】:

  • 优化查询和优化插入是不同的事情。优化您已经使用的插入 append nologging - 尝试缓存序列以节省更多时间 ALTER SEQUENCE SEQ_RESULT_ID CACHE 1000;
  • 序列已经缓存到1M,但还是很慢。还有什么想法吗?
  • pmresult 中有多少行?您选择的百分比是多少?
  • pm 表包含 79227256 条记录,而结果表包含 24 条记录。我们选择了每个人的近 99%。
  • @haki nologging 不是真正的提示。但这不应该阻止 append 工作。

标签: sql performance oracle parallel-processing oracle11g


【解决方案1】:

改进统计数据。 估计行数为 1,但实际行数超过 700 万并且还在增加。这会导致执行计划使用嵌套循环而不是哈希连接。嵌套循环更适合少量数据,散列连接更适合大量数据。解决这个问题可能就像确保相关表具有准确的最新统计信息一样简单。这通常可以通过使用默认设置收集统计信息来完成,例如:exec dbms_stats.gather_table_stats('SIRS_UATC1', 'TBL_RECON_PM');

如果这不能改善基数估计,请尝试使用动态采样提示,例如 /*+ dynamic_sampling(5) */。对于这样一个长时间运行的查询,如果能够带来更好的计划,那么值得花一点额外的时间预先采样数据。

使用语句级并行而不是对象级并行。这可能是并行 SQL 最常见的错误。如果您使用对象级并行,则提示必须引用对象的 别名。从 11gR2 开始,无需担心指定对象。此语句只需要一个提示:INSERT /*+ PARALLEL(16) APPEND */ ...。请注意,NOLOGGING 不是真正的提示。

【讨论】:

  • 语句级别的并行性是否适用于插入列列表,如INSERT /*+ parallel(16) */ tab (col1,col2) SELECT a1,b2 from tab2; ??它似乎对我不起作用。另一方面,当我也并行化 SELECT 时,它确实有效。
  • @Annjawn 我已经看到它工作了很多次。这是一个示例,虽然它不能直接运行,因为 SQL Fiddle 没有足够的功能:sqlfiddle.com/#!4/be5ddf/2
  • 有趣。我不确定为什么它对我不起作用。除了存在列列表时,所有其他并行 DML 都可以正常工作。
  • @Annjawn 即使在我的 SQL Fiddle 中使用相同的示例?这可能是一个有趣的问题。
【解决方案2】:

尝试使用更多的绑定变量,尤其是在可能发生嵌套循环的地方。我注意到您可以在以下情况下使用它

CREATE_DT >= :YOUR_DATE instead of CREATE_DT >= sysdate - 60 

我认为这可以解释为什么在执行计划的最低部分有 1.8 亿次执行,即使更新查询的整个其他部分仍然是 7900 万中的 800 万。

【讨论】:

  • 谢谢。这样做之后,执行时间缩短到了 11 分钟!
  • 我不明白为什么添加绑定变量会改进这个查询。一般来说,绑定变量向优化器提供较少信息,并导致更差的估计。我有一种感觉,这里还有其他事情发生。看到两个版本的查询的dbms_xplan.display_cursor 会很有趣。
  • 太棒了,也为我工作。用绑定变量替换所有内容。谢谢
【解决方案3】:

我可以看到两个大问题:

1 - 提示并行(在选择中)NO NOT 工作,因为它应该是这样的 +PARALLEL(T1,16)

2 - SELECT DO NOT 最佳,最好避免表达式 NOT IN

【讨论】:

    猜你喜欢
    • 2016-03-28
    • 2019-06-03
    • 2019-11-24
    • 2020-10-18
    • 2013-12-02
    • 1970-01-01
    • 2018-07-14
    • 2013-08-07
    • 1970-01-01
    相关资源
    最近更新 更多