溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

分而治之:Oracle 18c及12.2分區(qū)新特性的N種優(yōu)化實踐

發(fā)布時間:2020-08-10 19:55:27 來源:ITPUB博客 閱讀:189 作者:tianxiaoxu 欄目:關系型數據庫

本文根據楊廷琨2018年5月11日在【第九屆中國數據庫技術大會】上的演講內容整理而成。

  講師介紹:

分而治之:Oracle 18c及12.2分區(qū)新特性的N種優(yōu)化實踐

  楊廷琨,高級咨詢顧問, ITPUB Oracle 數據庫管理版版主 ,人稱“楊長老”,十數年如一日堅持進行Oracle技術研究與寫作,號稱“Oracle的百科全書”。迄今已經在自己的博客上發(fā)表了超過3000篇技術文章。2010年,與 Eygle 共同主編出版了《Oracle DBA手記》一書,2007年被 Oracle 公司授予ACE 稱號。

  分享大綱:

  ·分區(qū)基本概念

  ·分區(qū)演進歷史

  ·分區(qū)最佳實踐

  ·分區(qū)最新特性

  正文演講:

  很高興,又和大家重聚在DTCC 2018的數據庫性能優(yōu)化專場。這次我想和大家分享與分區(qū)相關的優(yōu)化特性,主要會和大家介紹一些Oracle最新的分區(qū)技術以及我們在日常運營中的最佳實踐。

  一.分區(qū)基本概念

分而治之:Oracle 18c及12.2分區(qū)新特性的N種優(yōu)化實踐

  Oracle對于分區(qū)的定義是根據內部定義的規(guī)則,將一張表的數據拆分到多個數據段中。分區(qū)之后,每個分區(qū)都是獨立的數據段。Oracle分區(qū)的最大好處是透明性,應用無需了解底層數據,訪問方式也與之前無異。換句話說,當把表做成分區(qū)表之后,程序不做任何的修改調整就可以直接跑,同樣如果把分區(qū)表改回普通表,也不要做任何調整。但是,這并不意味著做了應用之后我們就不需要了解表是否進行了分區(qū)。如果你想要分區(qū)帶來額外的性能好處,那么分區(qū)策略一定是要和應用程序、業(yè)務訪問方式相結合。

  Oracle提供了幾種分區(qū)的訪問方式,最常用直觀的方式是通過分區(qū)擴展語句直接指定到某個分區(qū)。但我們不推薦這種方式,我們更推薦的方式是通過真正控制訪問數據、增加規(guī)范條件,讓Oracle幫你定位到需要訪問的某些數據。

  分區(qū)的好處是什么?原來所有的操作都是基于一張大表去做的,而分區(qū)之后,一張大表化成了多個小單元,我們可以基于這種小單元去做刪除、截斷、遷移、索引等操作,分區(qū)提供了很好的細粒度操作手段。

分而治之:Oracle 18c及12.2分區(qū)新特性的N種優(yōu)化實踐

  提到分區(qū),很多人第一反應是它帶來的性能優(yōu)勢,但其實我認為分區(qū)最大的優(yōu)勢是在可管理性和可維護性方面,管理很多小表或者小數據段的成本要遠低于管理一張大表,而且平均維護時間也會變少,但速度卻會更快。

  第二個好處是可用性的增強,這也是Oracle官方宣稱的好處。原來,如果一張表對應的某個數據文件出現問題,影響的是整個全表,但現在可能影響的只是其中一個分區(qū),因為它在邏輯上是相隔離的。

  基于以上兩點,我們才能開始講性能的提升。在早期的版本中,Oracle只是直接說性能有一定提升,但其實這種說法是不準確的,因為分區(qū)如果設計不好,你的性能是會下降的。后來Oracle自身也意識到了,所以從Oracle 11版本之后,Oracle就把性能拆成了OLTP和OLAP兩種不同的情況去考慮。

  OLTP處理的更多的是短時間內的大量并發(fā),所以這時分區(qū)能帶來的好處是降低共享資源的爭用,消除熱點塊;OLAP面臨的是海量數據的處理,所以我們要更好的利用并行來提升性能。

  二.Oracle分區(qū)演進歷史

分而治之:Oracle 18c及12.2分區(qū)新特性的N種優(yōu)化實踐

  Oracle最早是從版本 8引進分區(qū)的,上圖這張表給大家列出了各個版本的分區(qū)功能,并通過功能、性能和管理性三個角度解讀。很多人雖然在用分區(qū),但是據我了解他們應用的很多特性都還集中在8、9版本,例如常用的范圍分區(qū)、歷史分區(qū)、列表分區(qū)等等功能。但其實之后的版本中,Oracle一直都有很多更好更新的功能提供給我們。

分而治之:Oracle 18c及12.2分區(qū)新特性的N種優(yōu)化實踐

  Oracle 12和18c中新增了很多非常實用的新功能,極大的簡化了大家的日常操作,接下來我會著重為大家介紹這些功能。

  三.分區(qū)最佳實踐

  接下來,我們介紹一下分區(qū)的最佳使用場景。

分而治之:Oracle 18c及12.2分區(qū)新特性的N種優(yōu)化實踐

  范圍分區(qū)的最佳使用場景是針對具有天然時間屬性的數據。例如,系統(tǒng)里記錄的訂單時間、生成時間、啟動時間等等。當然并不是只要有時間屬性數據就可以用范圍分區(qū),還要看業(yè)務對時間是否有可見性的要求。另外,業(yè)務如果更關心近期數據就再好不過了,這樣范圍分區(qū)對性能提升以及過期歷史數據清理都會是很好的幫助。

分而治之:Oracle 18c及12.2分區(qū)新特性的N種優(yōu)化實踐

  隨著數據的不斷積累,我們都會擔心數據庫越來越大。如果業(yè)務對于數據的生命周期有明確要求的話,那么我們可以通過清理數據來讓現有系統(tǒng)維持在一個相對穩(wěn)定的狀態(tài)。

  如何去清理數據呢?傳統(tǒng)的Delete數據清理會面臨很多問題,例如效率低下、無法釋放空間等等。但如果我們的數據存儲有一個明確的時間限定條件,那么分區(qū)就是一個很好的選擇。

  分區(qū)的清理成本和速度都很值得期待。在清理數據時,我們建議盡可能建立全局索引。數據清除操作是會影響全局索引的使用度,甚至導致索引失效。但如果我們是定期做分區(qū)數據清理的話,那么就不會影響全局索引的作用。

  范圍分區(qū)的好處是什么呢?首先,數據分布是相對平均的,因為是按照時間等分的,數量也是可控的;通過DDL清理數據的速度很快,不會產生大量redo、undo的問題。同時,在設計時還要考慮盡量讓一個查詢集中在一個分區(qū)中完成,提升查詢效率。通過定期DDL方式清理分區(qū),可以保證分區(qū)、表的大小維持在穩(wěn)定的量級,同時索引也不會隨著時間迅速增長。

  剛才我們介紹了范圍分區(qū)是最常用的清理過期數據的方式,但是在真正的產品環(huán)境中,我們會面臨各種不同的場景。例如,我們不能把所有數據都簡單的刪掉,因為刪除的數據中可能有少量的數據是需要保留的。

  面對這樣的場景,如果使用Delete方式去刪除,你會發(fā)現雖然我們使用了分區(qū),但是卻沒有享受到分區(qū)的好處。而且數據清理使用了原來的方式,那么必然會碰到原來的問題。

  那我們有沒有更好的解決辦法呢?我們可以用Insert+Exchange的方式來做,我先把這部分數據從表中刪掉,如果這其中有少量需要的數據,再插回來就可以了。這種方式既保證了效率,也避免了遇到之前的問題。

分而治之:Oracle 18c及12.2分區(qū)新特性的N種優(yōu)化實踐

  上圖是我通過代碼簡單的給大家演示一下整個過程。

  這里有一張T_PART表和P(3)分區(qū),假設這其中有七八千條數據都是不重要的,但其中可能需要保留30條數據,那么我就會采用之前提到的Insert+Exchange方式。這里還有一個小竅門,我們是先Insert,再Exchange。為什么這樣做,如果這張表一致性非常重要,我們就要在操作之前,先把這張表鎖起來,避免別人對它進行操作,然后把需要保留的數據Insert到一張臨時表中,之后再去做Exchange。通過這種方式我們可以時刻保持數據的一致性。

分而治之:Oracle 18c及12.2分區(qū)新特性的N種優(yōu)化實踐

  除了上面的挑戰(zhàn),我們可能還會面臨主子表的挑戰(zhàn)。假設我的主表和子表都做了分區(qū),那我們可能會面臨以下挑戰(zhàn),首先子表可能不存在主表的分區(qū)時間列,例如,有訂單表和訂單詳細表兩個表,并且兩者是主子表關系。其中訂單表是以訂單時間來分區(qū)的,這時訂單詳細表的分區(qū)時間列就會產生爭議,如果是按照訂單明細的創(chuàng)建時間,那么它和訂單時間可能是不一致的,且二者本身就是一對多的關系,所以在數據清理的時候,可能主表清理不了,如果要用訂單時間去分區(qū),那么你就需要在表中冗余訂單時間。

  如果只是冗余訂單時間,相信很多人都是可以接受的,但是挑戰(zhàn)還不止于此,一旦有了外健約束,主表無法執(zhí)行truncate操作,必須先將約束disable掉,給運維增加很多不便。

  如何解決這個問題?Oracle 11g就給我們提供了一個新功能叫參考分區(qū),它是這么解決的:主表的字段還是按照主表時間列去分區(qū),但子表不再需要冗余主表字段,而是直接依賴與主表的主外鍵關系去做分區(qū)。

分而治之:Oracle 18c及12.2分區(qū)新特性的N種優(yōu)化實踐

  參考分區(qū)適用于主子表建立相同的數據策略,同時子表沒有合適的分區(qū)字段,且主子表經常關聯訪問的場景。另外,Oracle 12還對此做了增強,支持級聯,換句話說,當我有主子表的情況時,不用先去子表做truncate,直接在主表做truncate,它就會遞歸的把所有子表truncate。

分而治之:Oracle 18c及12.2分區(qū)新特性的N種優(yōu)化實踐

  哈希分區(qū)相對來說比較簡單,它的適用場景是沒有時間屬性、缺少區(qū)分數據的業(yè)務字段的場景。如果系統(tǒng)面臨著共享資源的爭用,也可以使用哈希分區(qū)。

  我建議哈希分區(qū)鍵值列盡量選擇重復度不高的字段,這樣不容易導致數據分布不均;分區(qū)數量最好是2的冪次方,這也是為了避免分區(qū)數量分布不均;針對沒有時間屬性和明確業(yè)務屬性的表,通常不會去做定期清理的策略,我更建議使用全局索引;另外,哈希分區(qū)索引可以有效的解決索引熱點塊的問題。

  有人可能會有這樣的疑問,既然我的數據沒有業(yè)務特點,為什么要分區(qū)呢?我們之前碰到過這樣一個案例,客戶的表量級非常大,400T的數據可能有395T的數據都在同一張表中 ,客戶面臨的問題是表可能存不下這么多數據,Oracle對于表容量沒有限制,但是對于表空間的容量是有限制的,這時你會發(fā)現如果不用分區(qū),這個問題就是無解的。

分而治之:Oracle 18c及12.2分區(qū)新特性的N種優(yōu)化實踐

  哈希分區(qū)可以解決的一個問題是熱點塊問題。為什么會產生熱點塊問題呢?對于OLTP系統(tǒng)來說,會有大量的數據插入。插入數據的類型一般有兩種,一種是主鍵,另一種是時間類。這兩組數據的共同點是新插的數據永遠是最大的,當多人同時做插入時,因為表是無序的,所以沒有影響,但索引是有序的,所以更新索引時會產生資源爭用。如果你是RAC架構,由于GC多節(jié)點之間的相互爭用,會導致熱點塊問題進一步加劇。

  傳統(tǒng)的解決方案是利用Oracle提供的逆鍵索引,把鍵值反過來,分散熱點塊。但逆鍵索引有一個很大的缺點,就是它雖然可以解決熱點問題,但卻不支持范圍掃描。

  哈希分區(qū)如何解決呢?我們創(chuàng)建索引,指定索引按照哈希方式分區(qū),然后指定分區(qū)數量。這樣做的好處是什么呢?原來我是一個索引,只有一個最高值,大家都去爭搶這一個最高值,但是現在我變成了32個分區(qū),有32個索引最高值,這時的資源爭搶就會少很多。當然,技術都是有兩面性的,在這種情況下,你再做索引范圍掃描時,就不只是要掃一棵索引樹,而是32棵索引樹,引入的額外開銷就會大許多。所以分區(qū)數量的選擇也是十分有講究的。

  列表分區(qū)最常見的是針對有某些業(yè)務屬性數據的場景。我們可以根據明確的業(yè)務特點去做分區(qū)。

分而治之:Oracle 18c及12.2分區(qū)新特性的N種優(yōu)化實踐

  地區(qū)字段是列表分區(qū)常見的候選鍵值列,數據分布和訪問方式確定分區(qū)鍵值劃分,同時我還建議設定一個DEFAULT分區(qū),假設,我們把國內的大部分省到列出來了,但是有一天有個沒有對應分區(qū)的省的數據進來了,如果沒有DEFAULT分區(qū)就會直接報錯,而有了這個分區(qū),數據就有容身之所了。

  列表分區(qū)與業(yè)務的匹配度更好,業(yè)務可以清楚的知道數據存在哪里,并且高效的找到,不用太多的使用Oracle內部的關聯和查詢。

分而治之:Oracle 18c及12.2分區(qū)新特性的N種優(yōu)化實踐

  常見的索引有兩種,一種是全局索引,一種是本地索引。分區(qū)的全局索引和單表上的索引沒有區(qū)別,不管表上有多少個分區(qū),只有一棵索引樹,所有的數據來自分區(qū)。這樣做的好處了,即使表做了分區(qū),訪問代價也不會增加,但缺點是如果你對下面的分區(qū)表做了一些DDL操作,那么很容易導致索引失效。

分而治之:Oracle 18c及12.2分區(qū)新特性的N種優(yōu)化實踐

  本地索引和表分區(qū)是一一對應的關系,當你在對表做數據操作時,Oracle同時也會對索引分區(qū)做操作,不會導致分區(qū)索引的不可用,同時本地索引還支持并行掃描和創(chuàng)建。

  本地索引的缺點是如果你要把主鍵創(chuàng)建成本地索引,那么主鍵必須包含在索引里面,而且無法保證每棵獨立的索引樹之間的數據一致性,所以必須把鍵值列加入其中來保證唯一性,但是這樣未限定分區(qū)的查詢將掃描全部索引分區(qū),這會增加額外的開銷。

分而治之:Oracle 18c及12.2分區(qū)新特性的N種優(yōu)化實踐

  最后,我們看一下用來消除熱點塊的哈希分區(qū)索引,索引雖然也會做分區(qū),但是與表數據沒有任何關聯關系,任何一個索引分區(qū)都可以去訪問所有的表,它的優(yōu)勢就是分散熱點。但缺點是訪問索引時需要訪問索引的每個分區(qū)才能得到完整記錄。

  四.分區(qū)最新特性

分而治之:Oracle 18c及12.2分區(qū)新特性的N種優(yōu)化實踐

  Oracle 12提供了很多新特性,這些新特性對于日常維護是非常有價值的,所以我們來為大家詳細介紹一下。

分而治之:Oracle 18c及12.2分區(qū)新特性的N種優(yōu)化實踐

  首先,我們來介紹部分分區(qū)。剛才我們講到常用的索引有兩種,全局索引和本地索引,那么部分分區(qū)的索引是什么呢?在實際環(huán)境中,我沒必要對所有分區(qū)都創(chuàng)建索引,很多歷史數據分區(qū)的訪問頻度是非常小的,沒有必要關注,部分分區(qū)索引剛好滿足這樣的應用場景,它可以把索引范圍壓縮到一個合理范圍內。

  假設創(chuàng)建了一張分區(qū)表,里面有9個分區(qū),分別存儲了17年和18年的數據,其中存儲17年數據的四個分區(qū)我們做了INDEX OFF操作,在創(chuàng)建索引時,我們會發(fā)現雖然創(chuàng)建了9個索引段,但做了操作的四個分區(qū)是不可用的,實際只創(chuàng)建了5個索引段。

  當你訪問部分分區(qū)索引時,它會直接把執(zhí)行計劃分成兩部分,一部分是在索引段里掃描,還有一部分是在對應內容里掃描。部分分區(qū)索引其實最大的改變是它可以分辨哪些索引是可用的,哪些是不可用的。

  如果在指定鍵值的同時再加上一個時間,那這個時間就是我們分區(qū)線。當我們訪問數據時,Oracle就可以根據時間知道我要訪問哪個區(qū),其它無需訪問的區(qū)雖然也是有數據的,但Oracle會在這里有個設置恒為假條件的filter,當訪問到這里時會直接跳到下一部分。

分而治之:Oracle 18c及12.2分區(qū)新特性的N種優(yōu)化實踐

  Oracle 12.1非常強大的一個功能點是索引異步維護。當創(chuàng)建范圍分區(qū)時,由于經常要做DDL的清理,所以不建議大家去建全局索引。但是Oracle 12解決了這個問題,假設1月4日對應數據分區(qū)里有31萬條記錄,3月5日對應的數據分區(qū)有近30萬條記錄,當我們去做創(chuàng)建分區(qū)操作時,花費時間大約為0.18秒,然后再檢查狀態(tài)時,不出意外,全局索引已經失效了。重建之后,我們在分區(qū)創(chuàng)建時加上一個Update Index的操作,因為要同步DDL操作,它會更新所有狀態(tài),很多人認為它會變得非常慢,其實它只用了0.17秒,比之前的0.18秒還要快。這是因為Oracle 12之后,它會自動給數據打標識,并不是真正同步去維護,而是在后臺異步維護,不僅提高了索引的可用性,同時還提高了效率。

分而治之:Oracle 18c及12.2分區(qū)新特性的N種優(yōu)化實踐

  Oracle 12.2很有意思的一個特性是自動列表分區(qū),我們之前建議在列表分區(qū)時一定要加上DEFAULT值,否則數據插入會報錯,尤其是當一張表只有一個Keyboard,在自動列表分區(qū)中插入數據是非常困難的。而Oracle提供的很方便的功能是在線把一張普通表轉換成分區(qū)表,這樣我就不會因為是分區(qū)表而引入停機、維護等。

  Oracle 18c中針對這種情況提供了更強的改變,例如我創(chuàng)建了一個分區(qū)表和三個索引,當我從普通表變成分區(qū)表之后,但我對分區(qū)表策略不滿意,可以直接通過Oracle語句來改變數據表策略,而且這個操作可以在DDL發(fā)生時在線去做。

分而治之:Oracle 18c及12.2分區(qū)新特性的N種優(yōu)化實踐

  最后一個功能是針對變更之后的索引,我們可以在線去做分區(qū)的MERGE操作,通過在線的方式把其中幾個分區(qū)合并。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI