2012-02-13 73 views
1

我有一個擁有3億行數的表。我需要從中刪除約300萬。我在這張桌子上沒有任何索引。數據將根據特定的日期列刪除。像建議一種從oracle中的巨大表中刪除小數據的方法

delete from table where column_name = '1-dec-2010' 

什麼是最好的解決方案來執行此操作?

  1. 索引列並執行刪除。
  2. 保持表,因爲它是即刪除不使用索引

使用索引將使用索引掃描+更新索引中刪除後的開銷。沒有索引將使用全表掃描。那麼是否有任何門檻說X百萬行索引比全表掃描更受歡迎?

+0

這是一次性的,還是正常的工作? – 2015-08-20 12:59:42

回答

1

您有以下選項(在效率的順序排列):

  1. 分區。 Enterprise Edition的額外費用選項。如果數據按天分區,那麼刪除給定日期的數據就像刪除當天的分區一樣簡單。快速,高效,美觀但昂貴(除非客戶可以獲得很好的折扣)。

  2. 創建一個新表並將要保留的數據複製到新表中(使用直接路徑插入)。放下舊桌子;重命名新表(或使用動態管理的同義詞)。在這種情況下,索引可能是有用的,但是由於選擇性不好,Oracle可能會忽略這種情況(只有大約1%的數據會被訪問;優化程序可能認爲這不值得處理索引)。 有關此選項,請參閱Tom Kyte's comments

  3. 使用指數。這肯定會加速查找需要刪除的記錄,但刪除操作仍然會非常緩慢(重做和全部)。

+0

嗨巴拉尼,謝謝你的回答。由於這是現有的表格,我們不會通過對其進行分區來改變結構。根據第二種選擇,我們在100M桌面上嘗試了它,但令人費解的是它比使用索引的簡單刪除慢。我甚至測試過從180M記錄中刪除3M,並且索引刪除比非索引刪除快。但我不確定數據超過300M時會不會發生同樣的情況。 – 2012-02-13 09:36:54

0

那麼,你是否刪除了固定的1%的數據?如果是這樣,並且不考慮分區,請執行以下操作:

  1. 在日期列上創建索引。
  2. 確保爲該索引和表收集優化程序統計信息。

運行查詢類似如下:

select di.table_name, di.index_name, di.leaf_blocks, 
     di.clustering_factor, dt.blocks 
    from all_indexes di 
     left join all_tables dt 
     on di.table_owner = dt.owner 
     and di.table_name = dt.table_name 
where di.index_name = 'my_new_index' 
  • LEAF_BLOCKS給你 指數 「數據塊」 的粗略尺寸。
  • CLUSTERING_FACTOR告訴你需要多少個表I/O來 通過該索引讀取整個表。
  • BLOCKS給你 塊的表的大小。

如果CLUSTERING_FACTOR是非常接近的BLOCKS的大小,則該表是更多或更少的存儲在索引中的順序。

所以,如果你刪除表的1%,看哪個更小:

BLOCKS,或((LEAF_BLOCKS + CLUSTERING_FACTOR)/100)

if塊是顯著更大的 - 可能是10倍大的量級 - 比計算表達式,那麼索引可能會加快刪除。

相關問題