簡體   English   中英

UPDATE語句Oracle 11g的替代方法

[英]Alternatives to UPDATE statement Oracle 11g

我目前正在使用Oracle 11g,假設我有一個包含以下各列的表(或多或少)

表格1

  • ID varchar(64)
  • 狀態int(1)
  • 交易日期
  • 噸其他列

該表大約有10億行 我想用特定的where子句更新status



    where transaction_date = somedatehere

除了普通的UPDATE語句,我還可以使用其他哪些選擇?

目前,我正在嘗試使用CTAS或Insert into select獲取要更新的行,並在使用AS COLUMN_NAME時將其放置在另一個表上,因此值已在新表/臨時表上更新,看起來像這個:



    INSERT INTO TABLE1_TEMPORARY (
        ID, 
        STATUS, 
        TRANSACTION_DATE, 
        TONS_OF_OTHER_COLUMNS)
    SELECT
        ID
        3 AS STATUS,
        TRANSACTION_DATE,
        TONS_OF_OTHER_COLUMNS
    FROM TABLE1
    WHERE
        TRANSACTION_DATE = SOMEDATE 

到目前為止,一切似乎都比正常的update語句更快。 現在的問題是,我想從原始表中獲取剩余數據,這些數據我不需要更新,但確實需要包含在更新后的表/列表中。

我最初嘗試做的是使用相同的where子句在同一原始表上使用DELETE ,因此從理論上講,應保留在該表上的所有內容都應該是我不需要更新的所有數據,現在讓我兩個表:



    TABLE1 --which now contains the rows that i did not need to update
    TABLE1_TEMPORARY --which contains the data I updated

但是delete語句本身也太慢或與原始UPDATE語句一樣慢,因此如果沒有delete語句,我就會明白這一點。



    TABLE1 --which contains BOTH the data that I want to update and do not want to update
    TABLE1_TEMPORARY --which contains the data I updated

為了獲得與WHERE子句相反的數據,我還可以使用其他替代方法(請注意,此示例中的where子句已簡化,因此我沒有在尋找NOT EXISTS / NOT IN / NOT EQUALS的答案加上那些條款比肯定條款還慢)

我已經排除了按分區刪除的問題,因為我需要更新和不更新的數據可以存在於不同的分區中,而TRUNCATE也可以存在,因為我沒有更新所有數據,而只是部分數據。

我是否將某種JOIN語句與T​​ABLE1和TABLE1_TEMPORARY一起使用,以過濾出不需要更新的數據?

我還想使用盡可能少的REDO / UNDO / LOGGING實現此目的。

提前致謝。

我假設這不是一次操作,但是您正在嘗試設計可重復的過程。

以某種方式對表進行分區/划分,以便使接觸的行不完全分布在所有分區上,而是局限於少數幾個分區。

確保您的交易暫時不會使用這些分區。

通常,對於每個分區/子分區,通常都將對其進行更新,並對所有行執行CTAS(我的意思是,即使保持不變的行也都進入TABLE1_TEMPORARY)。 然后交換分區並重建索引分區。

最后,重建全局索引。

如果您沒有Oracle Enterprise Edition,則需要CTAS整十億行(緊跟着ALTER TABLE RENAME而不是ALTER TABLE EXCHANGE PARTITION),或者使用視圖准備某種“窮人分區”(SELECT UNION) ALL SELECT UNION ALL SELECT等)和一堆表格。

這種混亂實際上有可能比UPDATE更快。

我並不是說這是優雅的還是最優的,不是說這是在Oracle中加快大型UPDATE操作的規范方法。

如何將UPDATE保留在同一表中,但將其分成多個小塊呢?

UPDATE .. WHERE transaction_date = somedatehere AND id BETWEEN 0000000 and 0999999
COMMIT
UPDATE .. WHERE transaction_date = somedatehere AND id BETWEEN 1000000 and 1999999
COMMIT
UPDATE .. WHERE transaction_date = somedatehere AND id BETWEEN 2000000 and 2999999
COMMIT

如果總的工作量可能是可管理的,這可能會有所幫助,但是將問題全部集中在一起是一個問題。 這種方法將其分成中等大小的碎片。

這樣,例如,可以使其他應用程序保持運行並查看其他工作負載。 並且可以避免在日志文件中進行單個繁瑣的事務。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM