【问题标题】:"truncate-create as select" instead of update“截断创建为选择”而不是更新
【发布时间】:2023-03-25 19:12:01
【问题描述】:

我有一个包含大数据的表,我想更新它。我有办法做到这一点。首先,复制原始表并将其截断。之后,我将使用 create 作为从表副本中选择。所以我不会使用更新表达式。是不是更有效?

【问题讨论】:

  • 为什么要在 CPU 和内存上增加额外的处理负载来复制整个数据?你在哪里插入新值/更新?更新命令只会获取锁并将行放入应该被编辑的缓冲区。
  • 我认为选择比更新更有效,尤其是在 oracle db 中。
  • 那么更新命令用在哪里?
  • create table1_copy as select t1.c1,t1.c2,t2.c3 from table1 t1, table2 t2 c3 field is updated field from table2 to table1然后;截断 table1 并插入 table1 select * from table1_copy
  • 为了回答您的问题,首先提出几个问题:表格的行数有多大?这些行中有多少会被更新?原表有外键约束吗?原始表上有索引吗?确实,有时 CTAS 操作(创建表作为选择)可以加快您的更新过程,因为它们不必维护引用完整性或维护索引。但是,这种方法并不总是适用于应用程序。

标签: sql oracle plsql oracle-sqldeveloper plsqldeveloper


【解决方案1】:

您的问题的答案实际上取决于更新影响了多少行。显然,将 100,000,000 行复制到另一个表中以更新一行是无效的。更新所有这些可能是有益的,因为插入通常比更新快。

在走这条路之前,我想了解有多少行正在更新。如果不是很多,那么适当的索引可能会提高更新的性能。

但是,您的方法的逻辑并不完全正确。我倾向于这样做:

create table temp_copy as
    select . . .
    from bigtable . . .;

您的逻辑在select 中。然后,截断大表并重新插入:

truncate table bigtable;

insert into bigtable
    select *
    from temp_copy;

【讨论】:

    【解决方案2】:

    Whhi 截断表格? 我假设您的表没有任何限制(如果您不能截断!)。 你更简单的命令重命名; 它将与其他方法一样快速。 你可以这样做(我拿你的代码):

    您的代码:

    truncate  table table1; 
    insert into table1 select * from table1_copy
    

    替换为:

    drop table table1 ;
    alter table table1_copy rename to table1;
    recreate index of  table1
    

    【讨论】:

    • 这种方法的一个问题是所有索引、触发器、约束、表空间分配、分区等在删除表时都会丢失,因此需要重新创建。此外,所有引用该表的对象,如包、过程、函数等都将失效。
    • 是的,我知道这一点,但我想没有像 fk 这样的约束(如果你有 fk,你就不能截断你的表)。对于索引,执行此方法会更快。对于其他信息(表空间、分区、触发器...),您可以轻松找到这些信息。我想您在生产过程中不会这样做(使用 truncate 方法,值不正确的时间可能会很棒)。好吧,您正在使某些程序无效,但这只是一秒钟。如果目标是尽量减少干预时间,也许这可能是一个好方法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-30
    • 2015-08-21
    • 1970-01-01
    • 1970-01-01
    • 2017-11-03
    • 1970-01-01
    相关资源
    最近更新 更多