为什么使用INSERT / * + APPEND * /?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么使用INSERT / * + APPEND * /?相关的知识,希望对你有一定的参考价值。

一个java程序正在批量插入Oracle表。它适用于100-200个记录,但它挂起超过4000条记录。

当我检查查询时,其中有INSERT /*+APPEND*/

什么是INSERT /*+APPEND*/,为什么在INSERT查询中使用它?程序是否因为这件事而悬挂?

答案

这是一个SQL优化器提示。在你的情况下,它很可能没有影响。也许这是一个不成熟的优化。

此提示应强制执行所谓的直接路径插入,它绕过Oracle的缓冲区高速缓存并将数据直接写入数据文件。数据附加在高水位线(HWM)之外 - 忽略表的可用空间映射,不触发触发器并且不检查约束。另一方面,这种类型的插入物是阻塞的。只有一个会话可以同时在特定表上使用它。

文档的摘录:

“只有INSERT语句的子查询语法支持APPEND提示,而不支持VALUES子句。如果使用VALUES子句指定APPEND提示,则忽略它并使用常规插入。使用直接路径INSERT与VALUES子句,请参阅“APPEND_VALUES提示”此提示仅在您将INSERT用作SELECT语句时才有效

 insert into <table> SELECT * FROM ....

当您插入值时,Oracle默默地忽略它。较新的Oracle版本也支持APPEND_VALUES提示。

如果要验证正在使用的提示打开Toad或SQL Developer,请选择会话浏览器,找到该特定会话及其当前的SQL和exec计划。当你在exec计划中看到类似"INSERT into TABLE CONVENTIONAL"的东西时,提示会被忽略。如果你看到"INSERT as SELECT",那么你正在使用直接路径加载。

另一答案

insert通常会查找表中的第一个空白区域以添加新记录。虽然这节省了空间,但有时可能会减慢操作速度。

/*+APPEND*/是一个hint,它导致insert语句总是,因为缺少一个更好的术语,将新插入的行附加到表的末尾。这可能会浪费一些空间,但通常会更快。如果你知道桌子中间没有太多空区域,那就特别有用了(也就是说,你没有在它上面执行很多deletes和updates)。

另一答案

它是ORACLE编译器提示。它是出于某种目的而不是评论。这个提示用于加速插入,所以我不认为它是挂起程序的原因。

但是,请让你的dba检查这个表正在使用的表空间中的可用空间。(你的dba会更好地理解这个声明:))

可能存在一个问题,即该表空间中的任何更多插入可用的空间非常少,dba应该能够解析。

为什么可用的空间更少?因为APPEND提示会浪费空间,如@Mureinik的上述答案所解释的那样,如果在该表中有太多频繁插入此提示,则可能会出现问题。

另一答案

/ * + APPEND * /

  • 称为直接路径插入。
  • 数据附加在高水位线(HWM)之外 - 忽略表的可用空间映射,不触发触发器并且不检查约束。
  • 只有一个会话可以同时在特定表上使用它

如果要检查正在使用的提示,请查找该特定会话及其当前SQL和exec计划。当您在exec计划中看到类似“INSERT into TABLE CONVENTIONAL”的内容时,将忽略该提示。如果您看到“INSERT as SELECT”,那么您正在使用直接路径加载

  • 仅支持INSERT语句的子查询语法,而不支持VALUES子句。
  • 如果使用VALUES子句指定APPEND提示,则会忽略该提示并使用常规插入。
  • 要将直接路径INSERT与VALUES子句一起使用,请参阅“APPEND_VALUES提示”此提示仅在将INSERT用作SELECT语句时才有效。
另一答案

我不知道“加速”插入,但我肯定找到了提示,是的,这就是Oracle所谓的 - 而不是注释 - 对于在我执行插入时保持记录顺序非常有用一个表到另一个表,当我在最后将命令与ORDER BY配对时:

INSERT /*+ append */ INTO MYAPP.COUNTRIES (ID, CODE, NAME)
SELECT ID, CODE, NAME FROM MYAPP.OLD_COUNTRIES_TABLE ORDER BY NAME ASC;
COMMIT;

我已经知道这只是一个巧合(参见S.O.的this thread),但我已经多次使用它了,现在,这至少是我最终的结果。如果你使用INSERTORDER BY,但是没有附加提示,ORDER BY会被忽略,并且完全没用,以确保记录可以根据它们的插入顺序进行检索(参见my proof in my answer, here)。

以上是关于为什么使用INSERT / * + APPEND * /?的主要内容,如果未能解决你的问题,请参考以下文章

我啥时候应该在 INSERT 期间使用 /*+ APPEND */

为什么使用sys.path.append(path)而不是sys.path.insert(1,path)?

nolog使用insert append和parallel

python的append insert extend pop del remove使用

python中List append()extend()和insert()的区别

在oracle中我反复运行insert /*+append*/ into tablename 和truncate tablename