问题描述
嗨,
我有一个生产数据库 (版本如下所示),有大约2000个表,每个有超过1000万行。
为了解决冲突,我在这些表中添加了一个时间戳列。用当前时间戳更新每行的最有效方法是什么,最少的表锁定周期和可能的存档日志生成周期,并提交每10,000行?
3次运行的平均时间为3天,它是标准版数据库,因此我无法生成AWR报告。谢谢
我有一个生产数据库 (版本如下所示),有大约2000个表,每个有超过1000万行。
BANNER -------------------------------------------------------------------------------- Oracle Database 11g Release 11.2.0.3.0 - 64bit Production PL/SQL Release 11.2.0.3.0 - Production CORE 11.2.0.3.0 Production TNS for Linux: Version 11.2.0.3.0 - Production NLSRTL Version 11.2.0.3.0 - Production复制
为了解决冲突,我在这些表中添加了一个时间戳列。用当前时间戳更新每行的最有效方法是什么,最少的表锁定周期和可能的存档日志生成周期,并提交每10,000行?
SET SERVEROUTPUT ON SIZE UNLIMITED DECLARE table_own VARCHAR2 (30); table_name VARCHAR2 (30); l_time TIMESTAMP := SYSTIMESTAMP; sqlstmt VARCHAR2 (1000); CURSOR table_cur IS SELECT a.owner, a.table_name FROM dba_tables a, dba_segments b WHERE a.TABLE_NAME = b.SEGMENT_NAME AND a.owner = b.owner AND a.owner NOT IN ('ANONYMOUS', 'APEX_030200', 'APEX_PUBLIC_USER', 'APPQOSSYS', 'CTXSYS', 'DBSNMP', 'DIP', 'EXFSYS', 'FLOWS_FILES', 'MDSYS', 'ORACLE_OCM', 'ORDDATA', 'ORDPLUGINS', 'ORDSYS', 'OUTLN', 'MDDATA', 'MGMT_VIEW', 'OLAPSYS', 'OWBSYS', 'OWBSYS_AUDIT', 'SPATIAL_CSW_ADMIN_USR', 'SPATIAL_WFS_ADMIN_USR', 'SI_INFORMTN_SCHEMA', 'SYS', 'SYSTEM', 'WMSYS', 'XDB', 'XS$NULL', 'SYSMAN', 'OLAPSYS') AND (a.owner, a.table_name) NOT IN (SELECT owner, table_name FROM dba_tab_columns WHERE column_name = 'LAST_DML_TIME' AND NUM_NULLS IS NOT NULL) ORDER BY b.bytes / 1024 / 1024 / 1024 DESC; BEGIN OPEN table_cur; LOOP FETCH table_cur INTO table_own, table_name; EXIT WHEN table_cur%NOTFOUND; sqlstmt := 'update ' || table_own || '.' || table_name || ' set last_dml_time = ''' || l_time || ''''; EXECUTE IMMEDIATE sqlstmt; i := i + 1; IF MOD (i, 10000) = 0 THEN COMMIT; END IF; END LOOP; CLOSE table_cur; END; /复制
3次运行的平均时间为3天,它是标准版数据库,因此我无法生成AWR报告。谢谢
专家解答
你已经错过了最快的方法:
将列添加为not null,默认为sysdate!
这是从11g开始的 “即时” 操作:
https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:2575782100346318728
您可以删除新列,然后再次添加。但是删除列会产生大量重做,并具有锁定含义。
幸运的是有一个快捷方式: 将列设置为未使用。这也是一次 “即时” 行动。然后,您可以将其添加回默认值,而不是null:
如果您不想这样做,则下一个最快的方法是执行 “创建即选择”。通过选择sysdate此处设置更新日期:
您可以使用dbms_redefinition在线执行此操作:
https://oracle-base.com/articles/10g/online-table-redefinition-enhancements-10gr1
https://oracle-base.com/articles/11g/online-table-redefinition-enhancements-11gr1
但这仍然是一个问题。添加默认列是我的首选方法。
将列添加为not null,默认为sysdate!
这是从11g开始的 “即时” 操作:
https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:2575782100346318728
您可以删除新列,然后再次添加。但是删除列会产生大量重做,并具有锁定含义。
幸运的是有一个快捷方式: 将列设置为未使用。这也是一次 “即时” 行动。然后,您可以将其添加回默认值,而不是null:
create table t as select level x from dual connect by level <= 10000; alter table t add ( dt timestamp ); alter table t set unused column dt; alter table t add dt timestamp default systimestamp not null ; desc t Name Null? Type X NUMBER DT NOT NULL TIMESTAMP(6)复制
如果您不想这样做,则下一个最快的方法是执行 “创建即选择”。通过选择sysdate此处设置更新日期:
create table t_updated as select c1, c2, ..., sysdate last_updated from t复制
您可以使用dbms_redefinition在线执行此操作:
https://oracle-base.com/articles/10g/online-table-redefinition-enhancements-10gr1
https://oracle-base.com/articles/11g/online-table-redefinition-enhancements-11gr1
但这仍然是一个问题。添加默认列是我的首选方法。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
Oracle RAC 一键安装翻车?手把手教你如何排错!
Lucifer三思而后行
596次阅读
2025-04-15 17:24:06
【纯干货】Oracle 19C RU 19.27 发布,如何快速升级和安装?
Lucifer三思而后行
567次阅读
2025-04-18 14:18:38
XTTS跨版本迁移升级方案(11g to 19c RAC for Linux)
zwtian
485次阅读
2025-04-08 09:12:48
Oracle数据库一键巡检并生成HTML结果,免费脚本速来下载!
陈举超
473次阅读
2025-04-20 10:07:02
【ORACLE】记录一些ORACLE的merge into语句的BUG
DarkAthena
457次阅读
2025-04-22 00:20:37
【ORACLE】你以为的真的是你以为的么?--ORA-38104: Columns referenced in the ON Clause cannot be updated
DarkAthena
432次阅读
2025-04-22 00:13:51
Oracle 19c RAC更换IP实战,运维必看!
szrsu
432次阅读
2025-04-08 23:57:08
【活动】分享你的压箱底干货文档,三篇解锁进阶奖励!
墨天轮编辑部
417次阅读
2025-04-17 17:02:24
火焰图--分析复杂SQL执行计划的利器
听见风的声音
362次阅读
2025-04-17 09:30:30
3月“墨力原创作者计划”获奖名单公布
墨天轮编辑部
358次阅读
2025-04-15 14:48:05