【问题标题】:update big table with 200mn data用 2 亿条数据更新大表
【发布时间】:2021-07-17 14:52:07
【问题描述】:

我想用 0 更新 NULL TFLAG 列。当表很大时,更新列的有效方法是什么。

stats:
-----
Size             144 GB
Num Rows         235,676,098
Number of nulls   33408624

create table ticket (hkey number , tflag number);
alter table ticket add constraint hkey_p primary key (hkey);

Insert into TICKET (HKEY,TFLAG) values (1,1);
Insert into TICKET (HKEY,TFLAG) values (2,1);
Insert into TICKET (HKEY,TFLAG) values (3,null);
Insert into TICKET (HKEY,TFLAG) values (4,null);
Insert into TICKET (HKEY,TFLAG) values (5,null);
Insert into TICKET (HKEY,TFLAG) values (6,null);
Insert into TICKET (HKEY,TFLAG) values (7,null);
Insert into TICKET (HKEY,TFLAG) values (8,1);
Insert into TICKET (HKEY,TFLAG) values (9,null);
Insert into TICKET (HKEY,TFLAG) values (10,1);
Insert i

【问题讨论】:

    标签: oracle plsql query-optimization oracle12c


    【解决方案1】:

    最快的方法可能是:

    create table ticket_new
    as
    select hkey, decode( tflag, null, 0, tflag ) tflag
    from ticket;
    

    如果你有资源,你也可以使用并行执行来做到这一点。

    然后将票重命名为ticket_old(作为备份) 将ticket_new 重命名为ticket

    一切顺利,您现在可以放弃 ticket_old。

    【讨论】:

      【解决方案2】:

      简单的答案是

      update ticket
      set hflag = 0
      where hflag is null;
      

      答案很长,这取决于。表是否同时经历大量事务?您可以添加and rownum < 10000(或您认为合适的任何其他数字)以减小事务大小。在更新之间添加提交以不保持记录锁定。但是如果并发事务不是问题,我会使用上面的更新语句,让数据库做它的事情。

      【讨论】:

      • 谢谢马丁,是的,交易是同时发生的。我想更新 200 百万中的 3300 万,拆分数据和更新将再次需要更多时间,在这种情况下,我将不得不在每组中运行 33 条 100 万的更新语句。你认为这是唯一的选择吗?
      • @kashi - 无论你做什么,你都必须触及所有 3300 万行。使用文本编辑器只需几分钟即可在 sql 文本文件中创建 33 个适当的 UPDATE 和 COMMIT 语句。那么执行起来大概不会超过几分钟,在oracle世界里,3300万条记录,虽然不小,但真的算不上那么大。
      • 好的,谢谢,我试试看。
      • 一旦你清理了这个,然后将你的列定义修改为“not null default 0”。这将防止不发生此问题。您很可能必须修复您的插入,因为如果插入指定为 null,则默认值将不适用,任何指定 hflag 的选择/更新也为 null。
      猜你喜欢
      • 2016-12-11
      • 1970-01-01
      • 1970-01-01
      • 2017-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-12
      相关资源
      最近更新 更多