2012-06-22 45 views
2

我有一個包含幾十億條記錄的表,只需要更新一個沒有條件的字段。Oracle試圖更新列

update <table name> set flag='N'這是我的更新查詢,需要很長時間。 如何快速執行此操作。

+0

先使用索引然後執行更新! – vijay

+2

Asha沒有條件,所以建表索引不會有幫助。除此之外,創建索引可能需要比更新更長的時間。 –

+0

@Asha:你可能不得不忍受它... –

回答

0

請勿更新。使用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; 

嘗試,因爲你刪除舊錶要小心。

0

首先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版本快。

2

如果你真的等不了那麼長時間運行更新,並且可以與標誌爲,而不是「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和默認值(這是有道理的)。

+0

我認爲你可以添加一個不帶空列的默認值,而不必等待幾分鐘或幾小時。它應該只需要1秒左右。在這裏閱讀:http://oracletoday.blogspot.nl/2007/10/fasttrue-for-adding-columns-in-11g.html的鏈接 – TTT

+0

@TTT感謝。我認爲'N'的默認值需要一些時間用於十億行,但我可能錯了(可能11g的處理方式不同)。 – tbone

+0

@TTT再次感謝,文章非常有趣。我會做一個快速測試,並用默認值更新我的答案,如果11g真的不需要使用默認值進行更新! – tbone