Oracle與DB2數據存儲模式的相關知識是本文我們主要要介紹的內容,接下來就讓我們一起來了解一下這部分內容吧。“Oracle的普通表即堆表,存儲數據時沒有順序可言,而Oracle的索引組織表是根據主鍵順序來存儲表中的數據的。”
記得第一次得知Oracle的這個特性時,幾欲昏倒,不啻是對數據庫世界觀的顛覆。意識到原來這兩種主流的RDBMS竟然能有如此大的區別。對於Oracle而言,大多數表的數據存儲是沒有順序的;而對於DB2,大多數表的數據存儲是按照聚簇索引(Cluster Indxe)來排序的,也就是說,DB2中大多數的表按照Oracle的分類規則都屬於索引組織表。
對於DB2,唯一的例外情況就是這個表沒有索引——只要哪怕有一個索引,即便這個索引沒有被顯式地指定為Cluster Index,DB2仍然會盡量按照這個索引的鍵順序來存儲表中的數據。
“對於普通表而言,Oracle保證數據插入到表中之後,數據的物理地址ROWID不會再發生改變。當然對表進行MOVE,或者ENABLE ROW MOVEMENT之後對分區表的分區鍵值進行修改等明確導致表數據位置發生變化的操作除外。也就是說,普通的增、刪、改不會導致現有記錄的物理地址發生變化。
即使記錄的長度發生了變化,導致當前數據塊中無法容納這條記錄,Oracle也會在原位置上留下一個ROWID信息,通過這個ROWID信息可以找到這條記錄的新的位置。這也就是行遷移、行鏈接的實現方式。雖然增加了額外的IO,但是確保了ROWID不發生變化。”
這就是所謂的Position Update,即普通的Update不會改變記錄的物理位置。當然也有例外,那就是:
1,記錄所屬表分區改變,那麼記錄肯定要移動到目標分區對應的物理文件中,位置改變在所難免;
2,記錄本身是變長記錄,這裡的變長是指“物理變長”,不僅指含有變長字段(Variable Length)的記錄,而且也指表屬性為COMPRESS YES的記錄(因為DB2 z的DATA COMPRESS是ROW COMPRESS),當變長記錄Update時,物理長度可能會變化,通常縮短都沒問題,仍然可以做到Position Update,但是如果增長的話,有可能原來的物理位置沒有足夠的空間存放增長後的記錄,所以記錄只能重新去尋找一個合適的空間安身,而在原來的物理位置存放一個指向新位置的指針(當然,指針本身肯定很短,原位置足夠存放得下),這就稱為Overflow。
也就是原來ROWID指向的物理位置是一個指針,指針指向新位置(或者也可能指向另一個指針,但最終會指向記錄實際的物理位置,從而形成一個較長的指針鏈(Pointer Chain),當然這種情況對性能的傷害會更大)。
“可以看到,前面提到的MOVE,以及一些導致ROWID發生變化的分區操作,在使得ROWID變化的同時,也會導致索引處於不可用狀態。”
問題來了。ROWID變化怎麼會導致索引處於不可用狀態呢?在DB2中,記錄的物理位置變化,或者ROWID的改變,對應的Index Entry會跟著改變。換句話說,如果一個update涉及索引字段(index key columns)的改變,那麼這個update至少包含兩部分內容,即對表的更新和對索引的更新。
“那麼現在存在一個問題,對於索引組織表而言,為了保證數據存儲是根據主鍵順序進行的,就必須根據數據的增、刪、改隨時調整表中數據的位置,這使得ROWID不發生改變這個前提無法實現。而對於索引組織表,第二個索引需要一個方法來找到表中數據的具體位置,因此也就有了邏輯ROWID。”
技術的差異體現在這裡了。對索引組織表,Oracle嚴格保證數據存儲按索引順序排列,也就是說在記錄修改時,在前端就調整記錄的位置。而DB2則不然,DB2是盡量去保證數據按照索引順序排列(聚簇),但並不嚴格和強求,記錄如果不能存放到最佳位置(按索引排序的理想位置),可以存放到附近的次佳位置或偏離最佳位置更遠。隨著記錄修改越多,聚簇的效率(Cluster Ratio)也就越差,所以需要重組(REORG utility),也就是DB2在後端通過重組來調整記錄的位置。因此,REORG在DB2中遠比Oracle中來的重要。
然而,在DB2的世界,第二個索引,或者叫次索引(Secondary Index),非聚簇索引(Non-Clustered Index),仍然是通過記錄的ROWID來找到記錄的物理位置,沒有邏輯ROWID的概念。只是,一個聚簇效率完好(Cluster Ratio=100)的索引,從索引的Leaf page上的entry通過ROWID指向數據data page的關系好比是梳理過的,順序排列的(如下圖上方的索引IX所示)。而非聚簇索引的entry到表data page的關系是亂序的(如下圖下方的索引IX2所示)。即便重組,也只會使表的記錄按照聚簇索引的順序重新排列,上方索引的Cluster Ratio=100,而不會使下方非聚簇索引的Cluster Ratio有質的改變。
“對於索引組織表,雖然存儲位置可能會經常發生變化,但是主鍵是必須存在的。如果不能通過物理位置來尋找,那麼通過主鍵來查找也可以找到這條記錄。不過Oracle的實現並不是這麼簡單。 邏輯ROWID除了包含表的主鍵信息外,還包括了這條記錄在索引創建時的物理地址信息。關於邏輯ROWID相信結構描述,可以參考:http://yangtingkun.itpub.Net/post/468/11363。而這個地址信息,就是用來實現物理猜的。
如果物理猜能夠在目標數據塊中找到這條記錄,那麼這個效率和物理ROWID的效率是一樣的,只需要一次IO就找到了目標。如果通過物理猜找不到對應的記錄,那麼Oracle只能通過邏輯ROWID中包含的主鍵信息,通過主鍵掃描來定位這條記錄,根據索引的層高,這個操作可能會多消耗幾次IO操作。”
對於DB2,通常情況下,記錄的存儲位置並不容易發生變化,update也是Position Update為主,盡管這是對cluster規則的一種破壞,但是DB2依靠後端的REORG來進行修復,而換取的好處是記錄在前端進行修改的性能。無論是聚簇索引還是非聚簇索引,DB2都通過ROWID來直接定位到記錄的物理位置,因此始終是物理ROWID,而無邏輯ROWID的概念。依據引文的觀點,Oracle的次索引的邏輯ROWID包含索引創建時記錄的物理位置。
但是,當記錄發生多次update後,這個邏輯ROWID能命中的概率會顯著下降,不得不借助主鍵(Primary Key)信息再繞回到聚簇索引上去定位數據記錄的位置。這裡有兩個問題值得注意:
1,Oracle為了維護cluster規則,記錄進行修改時前端的性能會相對較差;
2,即便這樣,cluster規則仍然會被破壞,邏輯ROWID的命中率較低,而必須多做幾次I/O,也就是從非聚簇索引再繞回聚簇索引。因此,Oracle對聚簇索引的依賴度更高。
結論:
DB2總是通過ROWID來定位記錄的物理位置,無論是聚簇索引還是非聚簇索引都一樣;Oracle通過聚簇索引的ROWID來定位記錄的物理位置,非聚簇索引的ROWID也包含主鍵信息以利用聚簇索引,但是采用了“物理猜”作為一個捷徑,即寄希望於記錄的物理位置在非聚簇索引創建後不改變。
可見,DB2的表數據的存儲大多數都是按索引排序的,而Oracle表數據的存儲大多數是無序的(這是多麼巨大的差異啊)。對這種索引組織表的應用,會有一些限制(比如更適合只讀表,等等),而update性能會較差。
關於Oracle與DB2數據存儲模式的區別的相關知識就介紹到這裡了,希望本次的介紹能夠對您有所收獲!