有人問到:
今天聽一個IBM的人說資料庫在update時是先刪除原記錄,然後在插入,對此我有些疑問,oracle好像不是這樣的,請大家能否闡述一下update的過程,更新主鍵和不更新主鍵的處理是否一樣?不勝感激。另外,那個IBM的人還說update和insert不是一個數量級的動作,我認為要具體分析,對同資料量的操作,update需要定位,但是慢多少呢?
答:
其他資料庫跟oracle可能不同 ,但是就 oracle 而言,update 的時候,如果存在索引欄位的更新,則刪除原索引條目(不是真正的刪除資料,僅僅是在該行標記為 刪除)插入新的索引條目,對於row本身的更新,是在行物理地更改,如果行的長度增加到當前位置無法容納,則行的位置被提到 block的最上面一條記錄的位置之上,假如該塊已經無法容納,則在原來行的物理位置保留一個指標,行被遷移到新的block,而保留的指標就是指向新的block的位置。這時索引中rowid不用發生變化,查詢的時候先找到 那保留的指標,再去找 實際的新的位置。假如行遷移後再發生update 又導致遷移,則oracle首先看原來的位置的block是否具有容納該行的空間,如果有就又遷移回去,如果沒有就遷移到新的 塊,修改原來最早塊處的指標。 也就是說不會存在2個指標的尋找才能找到 行.更新的時候,變化前後變化後的資料都被寫入 redo ,變化前資料還被寫入 復原段,變化後資料被應用於 data buffer 。
若假設存在表t(a,b,c)
update t set a = ... where b = ... and c = ...
則復原段中只記錄 a 的變化前的值,關於update 的時候通常需要通過索引去定位,否則是全表掃描就很慢了
而insert 則只是找個 block 插進去,兩者的差異可能很大,可能完全不是一個數量級的時間和資源的消耗
更多的詳細的探討請參考:http://www.itpub.net/showthread.php?threadid=129524