我正计划在我的巨大表(超过十亿行)上执行长时间运行的更新。此更新将按固定数字乘以一列的值。PL/SQL - 不更新已更改的行
问题是,在我的更新(可能会持续几个小时)期间,肯定会有短事务更新某些行,并且这些行将具有不应更新的正确值,尽管它们仍会满足我的更新条件。
所以,问题是 - 我怎么跳过(不更新)这是我的长时间运行更新的事务之外更新行?
我正计划在我的巨大表(超过十亿行)上执行长时间运行的更新。此更新将按固定数字乘以一列的值。PL/SQL - 不更新已更改的行
问题是,在我的更新(可能会持续几个小时)期间,肯定会有短事务更新某些行,并且这些行将具有不应更新的正确值,尽管它们仍会满足我的更新条件。
所以,问题是 - 我怎么跳过(不更新)这是我的长时间运行更新的事务之外更新行?
哦,我完全忘了这个问题。 因此,我最终通过将其副本保存到另一个表(我不得不更新那些满足给定条件的行)来制作当前行的快照。之后,我更新了未更改其值的行(使用合并)。
一种方法是使用FOR UPDATE SKIP LOCKED,这样其他会话将无法挑选已被选中更新的行。
例如,
会议1:
SQL> SELECT empno, deptno
2 FROM emp WHERE
3 deptno = 10
4 FOR UPDATE NOWAIT;
EMPNO DEPTNO
---------- ----------
7782 10
7839 10
7934 10
SQL>
会话2:
SQL> SELECT empno, deptno
2 FROM emp WHERE
3 deptno in (10, 20)
4 FOR UPDATE NOWAIT;
FROM emp WHERE
*
ERROR at line 2:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
现在让我们跳过其通过会话1
锁定的行SQL> SELECT empno, deptno
2 FROM emp WHERE
3 deptno IN (10, 20)
4 FOR UPDATE SKIP LOCKED;
EMPNO DEPTNO
---------- ----------
7369 20
7566 20
7788 20
7876 20
7902 20
SQL>
所以,部门= 10是由会话1,然后锁定部门= 20由会话2
我已经做了一些你的问题锁定,但我的表是不是过于庞大喜欢你。
我重新设计了我的表格,添加了2列。
created_date:插入数据时触发器将sysdate放入。
modified_date:更新数据时触发器将sysdate放入。
然后我可以在我的where子句中使用created_date或modified_date。
例子:
UPDATE TABLE table_name
SET column_name = 'values'
WHERE created_date < SYSDATE;
我希望这会帮助你。
这是我的第一个想法,但不幸的是,修改表结构不是一个选项。 –
让我们假设在您运行长交易时短交易不会来。但是,在开始长交易之前,存在一些已经运行并更新了一些行的短交易。所以,这些行将是正确的。你怎么知道跳过它们? (我想说的是,你的问题没有什么事务大小或并发性,但数据质量和一致性) –