【问题标题】:What is the less expensive method of inserting records into Oracle?将记录插入 Oracle 的成本更低的方法是什么?
【发布时间】:2015-04-19 21:36:51
【问题描述】:

我需要能够重复处理 XML 文件并将大量数据插入 Oracle 数据库。该过程需要能够创建新记录,或者如果数据已经存在,则更新现有记录。

我可以想到两种方法来处理将 100,000 条记录插入/更新到 Oracle 数据库中。但哪种方法更好?还是有别的办法?

  • 尝试插入。如果没有例外,插入工作并且一切都很好。如果出现异常,请捕获并执行 UPDATE。
  • 首先查找记录 (SELECT)。如果找不到,请执行 INSERT。如果找到,请执行 UPDATE。 显然,如果 Oracle 表是空的,那么第一种方法通过前面的查找可以节省时间。但是如果该文件之前已导入,然后有人更改了几行并重新导入,则生成的异常数量将变得巨大。 由于查找,第二种方法在空数据库上花费的时间更长,但在后续导入期间不会产生代价高昂的异常。

是否存在处理此类数据的“正常”模式?

谢谢!

【问题讨论】:

    标签: sql database oracle


    【解决方案1】:

    我不知道“该”模式是什么,但如果您正在生成一个语句,那么也许您可以生成一个包含 XML 文件中所有数据的 select from dual 查询的联合。然后,您可以将此 select 包装在 MERGE INTO 语句中,因此您的 SQL 看起来像:

    MERGE INTO YourTable t
    USING (
      SELECT 'Val1FromXML' as SomeKey, 'Val2FromXML' as Extrafield, 'Val3FromXML' as OtherField FROM DUAL
      UNION ALL
      SELECT 'Val1FromRow2' as SomeKey, 'Val2FromXML' as Extrafield, 'Val3FromXML' as OtherField FROM DUAL
      ...) x ON x.SomeKey = t.SomeKey
    WHEN MATCHED THEN
      UPDATE SET 
        t.ExtraField = x.ExtraField, 
        t.OtherField = x.OtherField
    WHEN NOT MATCHED THEN
      INSERT (ExtraField, OtherField) VALUES (x.ExtraField, x.OtherField)
    

    这个语句的优点是它只有一个语句,所以它节省了为每一行初始化一个语句的开销。此外,作为单个语句,它将完全失败或完全成功,否则您将通过事务完成。

    这也是一个陷阱。对于这样的导入,您可能希望一次只执行有限数量的行然后提交。这样您就不会将表的大部分锁定太久,并且您可以中断导入并在以后继续。但幸运的是,为有限数量的行生成 MERGE INTO 语句也应该很容易,只需在联合的 select-from-duals 中放置不超过 500 行。

    【讨论】:

    • 看起来很棒 - 我会试试这个。谢谢!
    【解决方案2】:

    “正常”模式是用external table 包装您的文件,然后执行upsert via the merge keyword

    根据您的硬件,通过 SQL*Loader 将文件加载到临时表中可能比使用外部表快得多。

    edit - 刚刚意识到您正在处理一个文件,而不是尝试直接加载它。 GolezTrol's answer 是处理您生成的行的好方法。如果数量很大,但我仍然建议填充临时表并考虑通过加载器单独加载它,而不是使用大量 SQL 语句。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-19
      • 2015-12-31
      • 1970-01-01
      • 1970-01-01
      • 2010-11-11
      相关资源
      最近更新 更多