【问题标题】:Update/Create table from select with changes in the column values in Oracle 11g (speed up)从选择中更新/创建表,并更改 Oracle 11g 中的列值(加速)
【发布时间】:2020-02-08 09:09:37
【问题描述】:

在这项工作中,我们有一个用于一些 Oracle 11g 数据库的更新脚本,大约需要 20 小时,并且一些最苛刻的查询是我们更改一些值的更新,例如:

UPDATE table1 SET
    column1 = DECODE(table1.column1,null,null,'no info','no info','default value'),
    column2 = DECODE(table1.column2,null,null,'no info','no info','another default value'),
    column3 = 'default value';

像这样,我们有很多更新。问题是这些表有大约 1000 万行。我们还有一些更新,其中某些列将具有默认值但它们可以为空(我知道它们是否具有非空和默认约束,那么这些列的添加几乎是立即的,因为这些值在目录中),然后更新或添加此类列会花费大量时间。

我的方法是重新创建表(正如 TOM 在https://asktom.oracle.com/pls/asktom/f?p=100:11:0::NO::P11_QUESTION_ID:6407993912330 中所说)。但是我不知道如何从原始表中检索一些列,这些列将保持不变,而其他列将更改为默认值(并且在更新之前,此类列具有合理的信息),这是因为我们需要对一些信息保密。

所以,我的方法是这样的:


CREATE TABLE table1_tmp PARALLEL NOLOGGING
    AS (select col1,col2,col3,col4 from table1);

ALTER TABLE table1_tmp ADD ( col5 VARCHAR(10) default('some info') NOT NULL;
ALTER TABLE table1_tmp ADD ( col6 VARCHAR(10) default('some info') NOT NULL;

ALTER TABLE table1_tmp ADD ( col7 VARCHAR(10);
ALTER TABLE table1_tmp ADD ( col8 VARCHAR(10);
MERGE INTO table1_tmp tt
    USING table1 t
    ON (t.col1 = tt.col1)
WHEN MATCHED THEN
    UPDATE SET
        tt.col7 = 'some defaul value that may be null',
        tt.col7 = 'some value that may be null';

我还尝试将可空值创建为非空值以快速完成,并且工作正常,问题是当我将列返回为空时,该操作需要太多时间。最后一个代码最终也消耗了大量时间(合并超过一个小时)。

希望对如何提高此类事物的性能有所了解。 提前致谢!

【问题讨论】:

  • 更新 1000 万行表的所有行需要一些时间。

标签: sql database oracle oracle11g


【解决方案1】:

最后,我用原始表中的数据创建了一个临时表,在创建时,插入默认值和解码以及任何其他东西,比如如果我想将某些东西设置为 NULL,我做了投掷。比如:

    CREATE TABLE table1_tmp AS (
        column1 default "default message",
        column2, --This column with no change at all
        column3, --This will take the value from the decode below 
     ) AS SELECT 
        "default message" column1,
        column2 --This column with no change at all,
        decode(column3, "Something", NULL, "A", "B") column3,
     FROM table1;

这就是我解决问题的方法。处理一个 2300 万行的表大约需要 3 到 5 分钟,而过去更新需要几个小时。现在只需要设置权限、约束、索引、评论,仅此而已,但这些东西只需要几秒钟。

感谢@thehazal 的回答无法检查您的方法,但听起来很有趣。

【讨论】:

    【解决方案2】:

    也许您可以在加入合并时尝试使用 NVL:

    MERGE INTO table1_tmp tt
        USING table1 t
        ON (nlv(t.col1,'-3') = nvl(tt.col1,'-3'))
    WHEN MATCHED THEN ....
    

    如果你不想更新空值,你也可以这样做:

    MERGE INTO table1_tmp tt
        USING table1 t
        ON (nlv(t.col1,'-3') = nvl(tt.col1,'-2'))
    WHEN MATCHED THEN .....
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-21
      • 1970-01-01
      • 2013-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多