我有一個包含幾十億條記錄的表,只需要更新一個沒有條件的字段。Oracle試圖更新列
update <table name> set flag='N'
這是我的更新查詢,需要很長時間。 如何快速執行此操作。
我有一個包含幾十億條記錄的表,只需要更新一個沒有條件的字段。Oracle試圖更新列
update <table name> set flag='N'
這是我的更新查詢,需要很長時間。 如何快速執行此操作。
請勿更新。使用CTAS,然後重命名新表。
CREATE TABLE T_NEW NOLOGGING PARALLEL AS
SELECT COL1, COL2, 'N' FLAG FROM T_OLD;
然後應用索引,約束或贈款從舊錶。如果你忘記了這一步,你將會受苦。
DROP TABLE_T_OLD;
RENAME T_NEW TO T_OLD;
嘗試,因爲你刪除舊錶要小心。
首先IDEEA: 如果你有空間:
create table tmp_tab as select col1, ..., coln, "N" as flag
from your_tab;
rename table your_tab to your_tab_old;
rename tmp_tab to your_tab;
會非常快相比,簡單的更新。
如果一切正常,請刪除your_tab_old。
二IDEEA:
update /*+parallel(your_tab 8)*/ your_tab set flag='N';
將 比NOPARALLEL版本快。
如果你真的等不了那麼長時間運行更新,並且可以與標誌爲,而不是「N」空住,那麼你就可以做到這一點非常快(未經測試,但應工作):
alter table my_tab set unused column flag;
alter table my_tab add (flag char(1));
如果您想回收一些空間(請注意,放置操作需要一些時間,因此如果您選擇這樣做時要小心),您可以稍後放棄未使用的檢查點。
希望幫助
編輯:感謝@TTT這個article,顯然是在11g中的Oracle可以存儲在數據字典中的默認值,而不是執行更新所有行(我從以前的經驗預期) 。這意味着您可以使用'N'值而不是NULL。 只要確保你指定NOT NULL和默認值:
SQL> set timing on
SQL> drop table test1
Table dropped.
Elapsed: 00:00:00.23
SQL> create table test1
(
col1 varchar2(10),
flag char(1)
)
Table created.
Elapsed: 00:00:00.14
SQL> insert into test1
select 'x','Y'
from dual
connect by level <= 1000000
1000000 rows created.
Elapsed: 00:00:02.09
SQL> alter table test1 set unused column flag
Table altered.
Elapsed: 00:00:00.07
SQL> alter table test1 add (flag char(1) default 'N' not null)
Table altered.
Elapsed: 00:00:01.01
沒有「NOT NULL」,只是默認情況下,它用了20秒,只顯示工程這個「快=真正的」把戲當指定不爲null和默認值(這是有道理的)。
先使用索引然後執行更新! – vijay
Asha沒有條件,所以建表索引不會有幫助。除此之外,創建索引可能需要比更新更長的時間。 –
@Asha:你可能不得不忍受它... –