日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Oracle之表分区、分区索引(一)

發布時間:2024/4/13 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Oracle之表分区、分区索引(一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
繼續往下講就是分區了

對于ORACLE來講,分區是咱們開發中最常用的,什么樣的場景下要進行分區,主要是針對于大數據量的表,頻繁查詢的表,我只是說數據量大的表,并沒有說物理的這個大,比如你搞一個文件表,數據庫文件,里面來一個file文件,你搞一個file文件這種表,然后你去做分區,那樣的話其實也不是很快的,我們這里說的怎么去做分區,是按照數據量來的,不是按照物理的大小來的,按照物理大小其實ORACLE應付不了太大的數據,資深的ORACLE DBA,做運維這方向,一個表得有多大嗎,多少個G嗎,你想不到,你們猜一猜,一張表,當然是存放file文件的表,存放一些圖片,還有一些其他的東西,你們猜一下這張表有多大,300G,就是一張表300G,你猜猜這張表有多少東西,就是一張300G的file表,就是那個文件表,就是怎么說呢,累積好多年的一些圖片數據,我問他怎么辦,沒什么解決的辦法,就是光備份就得備份好幾天,因為什么啊,大數據你可以存在其他的地方,你這么大的數據量,當然DBA不是JAVA這個方向,就是再索引你這個也太大了,就是300G,你想想,300G是什么概念,一張表300個G,像有些需求啊,咱們去做項目的時候,也會有張文件表,數據庫里面必須有張文件表,文件表應該存一些比較特殊的文件信息,你像一些無關緊要的信息,卻還是很海量的信息,我們一般是放在類似于數據倉庫,和文件服務器上,咱們在數據庫里面給一個字段,給一個文件服務器的路徑,給他寫到里邊,然后瀏覽器直接訪問這條記錄的時候,有一個path路徑,直接到界面上能夠顯示出來,都是這么去做的,當然也是好多年了,也沒人去管,好了不用討論這個事了,首先咱們說分區的事,ORACLE表分區最好一個區間不要大于500W條,500W條應該是一個工作限,你按什么分區,一個區間500W條數據,這個東西你要自己去衡量,自己去判斷的,首先分區,怎么去做分區,使用什么分區,還是用實際的業務邏輯去考慮的,ORACLE 11g提供了7種的分區功能,非常強大,滿足90%以上的需求,一般來講咱們隊分區應該是非常的有了解了,應該是這樣的,ORACLE里面一共分這些種,咱們一起來看一下,range分區,hash,list,復合,間隔,system,這7種分區,首先說第一種分區

咱們的range分區,range分區其實就是區域分區,就是你從邏輯上給我劃分一個區域,然后按照這個區域把這個表進行一個分區,原先的一個數據庫表存在一個文件里,就是咱們對應的數據庫文件里,那現在我做分區了以后,就是把多個表拆分成了多個塊,就是有多個數據庫文件,那么大家想一件事,你說這樣去做分區的話,畫個圖,就是我分區的概念是什么啊,我在這里簡單的說一下,無論你怎么樣的分區,其實都是一樣的,都是一個概念,就是原先咱們一張表不做分區的時候,咱們的一個表是存在數據庫一個文件上的,就是咱們磁盤上有一個小文件,專門就對應這張表去存,這個文件就存這個表的信息,然后我分區了以后,就相當于什么,相當于不存在一個地方了,把第一個區間,第二個區間,第三個區間,分別的放在不同的物理的位置,可能有3個文件,那么現在問題就產生了,咱們的語法必須得結合create table去實現,就是說什么啊,你在創建表的時候,然后緊連著指定partition,你不能先創建表,表創建完了以后你再去指定partition,這是不行的,你只能是創建表的時候一并去指定partition,去指定分區,只有這樣才行,因為你一旦表創建完了之后,一個數據文件已經創建完了,就是我這個表所有的數據都放在這個文件里了,所以你再分區,這個表去拆成幾個文件,這個不現實,一些運維的手段,運維什么手段呢,利用一些抽取工具一部分一部分的逐漸的去建立,所以說這些都不是咱們要考慮的事了,就是現在要告訴你的事情是create table的時候,直接指定加上partition,這樣的話才能一個表按照你的物理的文件去存儲,所以說為什么語法是這樣的呢,就是因為這個原因,以表單位還是以庫為單位,這個你自己可以去定義,這個就無所謂了咱們先看一個小例子吧,首先我就create一個table,然后指定一個分區,就可以這樣去做,你把咱們來寫一寫吧,現在我就來寫一個分區的小例子,我這個分區也是有小例子的,所以我就不怎么想去寫他了,創建一個SQL Window,看這個例子吧,首先我是做什么事呢

range分區,是按照區域進行分區,分區一定是在create table的時候進行指定的,這是要記住的一個問題,我們先看看數據庫里面有沒有相關的一個表,也沒有,因為創建一個table叫做sale,薪資,兩個字段,一個叫product_id,一個叫sale_count,一個是id,一個是計數,然后這個數就隨隨便便寫了一個,現在這個表創建完了以后,正常來講這里要打一個分號,但是我沒有這么去做,我直接說partition by,指定range分區,然后括號里面的內容是什么意思呢,指定分區的字段是什么,說白了就是指定分區的字段是什么,就是咱們上節課講的MYSQL,我可以指定一個type類型,一個type類型做什么事啊,我按照type等于1的,里面可能有10條數據,10條數據可能有5條數據等于1,有5條type等于2,然后把type等于1的放到另外一個數據庫中,或者是另外一個表中,這里面放這5條,剩下的都等于2了,就是這個意思,這個其實也是一樣的,咱們要指定的分區是什么,按照這個sale_count去做一個分區,然后現在我既然指定是range分區,所以說我要指定區間,partition p1,分區的名稱是你自己去定義的,我指定一個p1,values less than(1000),這什么意思,也就是小于1000的這個數值,給我放到p1這個區間,小于等于2000的放到p2這個區間,小于等于3000的放到p3這個區間,現在咱們去創建一下,創建完了以后咱們在數據庫里面多了一個表了,select * from SALE,他和普通的表沒有任何的區別

沒有什么變化,無非就是一個SALE,你從這里看不出有什么特點,包括你查詢的時候也看不出有什么特點,那怎么能看出特點呢,咱們應該看這個,查看分區的情況,應該看這個,這個是所有的分區的情況,select * from user_tab_partitions,不僅僅是這一張表的情況,user_tab_partitions,select這張表,之前也會建立很多分區,很多IVERTAL分區,其他你不考慮,首先你看這三個,SALE這個table,已經指定了三個分區,PATITION_NAME是p1,p2,p3,然后就是HIGH_VALUE,就是他的上限,這個上限是1000,這個上限是2000,下面的肯定是3000了,還有些其他的字段,他這個字段很多,就不詳細去說了

其實你還可以更詳細的去看這張表,下面也有,select * from table partition(p1),select * from sale這張表,SELECT * FROM SALE PARTITION(p1),我們可以這樣去查

我可以去查,當然我們剛才分了三個區間,P1,P2,P3,我可以這么聯合的去查SELECT * FROM SALE PARTITION(P1);SELECT * FROM SALE PARTITION(P2);SELECT * FROM SALE PARTITION(P3);這三個區間的數據可能都是空的,現在我就去做一個插入的操作,INSERT INTO SALE VALUES('1',500);INSERT INTO SALE VALUES('1',1300);INSERT INTO SALE VALUES('1',2441);commit;INSERT INTO SALE VALUES('1',3500); 第一個字段可能是一個字符串的值,這里面有一個number,比如說是100,咱們多插入幾個,他這里是1000,第一個是500吧,第二個是1300,第三個是2000到3000之間的區間,那我2400,隨便給個值,然后再來一個3500,現在先把這三條數據插進去

然后我SELECT * FROM 表的時候你還是看不出來

三條數據還是這樣的,你看不出任何的變化,沒有任何的特點,物理分區會降低查詢速度嗎,不會啊,分區的目的就是為了提高查詢的速度,那現在咱們做完這個事了,然后查詢出來也沒有任何的特點,你再去查這三張表

第一個分區,你看我查P1的時候,他就一條數據,然后我查P2的時候,也就這么一條數據

然后我再查P3的時候,2441

也就是說你按照什么分區字段走,然后你根據上面的分區規則,他就把數據塞到不同的分區里了,大體上就是這個意思,咱們現在就做著事情INSERT INTO SALE VALUES('1',3500);現在我們的分區只是三個區,那我現在想插3500,你覺得能插進去嗎,就是我現在想插一個3500的數據,我能不能插入到這個表里,肯定是找不到位置,插入的關鍵字未映射到任何的分區,說你這個值已經超了我這個分區了,那咱們想一下,既然插入不進去,一定要再給分區做一個擴展,肯定是支持擴展的,添加和刪除分區其實都可以去做,添加就是alter tabletableName add partition p4 values less than(maxvalue),你可以去再指定4000什么的,然后你還可以去指定一個最終的值,maxvalue,就是無限大,你如果指定這個值的話,那就相當于給這個表指定一個上限了,就是畫了一個句號了,你這塊如果是maxvalue的話,就是max到3000都會放到這一個區間里,你可以正常再來一個4000,或者5000,這都是可以的,但是不要輕易去加這個東西,你這樣你這個分區就相當于固定了,這表叫SALE

你會發現現在就有第四個了,然后這里面的最大就是MAXVALUE了,那無論我是插入3500也好,插入一個8000也好,還是插入1萬也好,總會放到第四個分區里,咱們commit一下

我現在繼續去查一下P4

你會發現P4,,3500,8800,都會放到第四個區間里,這就是你對分區的一個擴展,然后咱們繼續往下走,然后你也可以刪除分區,drop,alter table tableName drop partition p4,可以把它干掉,我們試一下吧,我把它干掉數據會不會丟失呢,想一想,咱們直接先操作吧,然后看結果,刪掉了之后,然后再來查一下我的partitions

還是三個區,我SELECT * FROM SALE

你就直接把他這個數據給他弄沒了

相當于把文件給刪除了,再往下看,然后有一個問題就是說,想做一個什么事呢,想想啊,我要做這個事情,我要做update操作,我要做一個update操作,我這樣去做update,你看我先做表里是這三條數據,我現在想把這條數據改一下,先改一下這個吧,因為我插入的時候可能插錯了,UPDATE SALE SET product_id = 3 WHERE sale_count = 500,因為我剛才不小心這個沒改過來,咱們再查一下這個表吧,我要1,2,3這個效果

把第一條記錄,SALE我想改了,我做一個UPDATE操作,把這個sale_count改掉,我去UPDATE,UPDATE SALE SET SALE_COUNT = 1500 WHERE PRODUCT_ID = 1;我先去做這個操作,我更新完之后能更新成功嗎,我現在要更新,更新這條記錄,我想把ID這條記錄,原先是500,準備改成1500,然后問一下能不能更新成功,能不能UPDATE成功,就目前來講,想一想,能不能進行UPDATE成功呢,目前是不能的,我進行UPDATE的時候,更新分區關鍵字列將導致分區的更改,本身我的數據原先是在第一個區間的,我現在想給他改成第二個區間,那這個肯定不行,當然其實也不是不行,也是可以的,只不過你得去做一個操作,在UPDATE之前你得做這個alter table SALE enable row movement;做一個這個操作,就是使他能行移動,我先做完這個事情

這個時候我再回來UPDATE就成功了

應該使他能移動,咱們先看第一個區間,就沒數據了

但是第二個區間里就有兩條數據了

ID等于1的數據是1500,在這個里面,可以去做這個事情,沒問題吧,是不是分區很簡單,首先分區簡單就這么幾個操作,這個能聽懂嗎,給我點反饋,很簡單吧,這個東西是公共的,比如我把這個1又改成500,我現在又給他改回去

我們都是在創建完表以后,就是在創建完partition以后,就直接加這么一句話,一般都是這樣的,剛才我已經又改了一次了,所以P1里還是會有數據的

咱們繼續往下看,分區這塊目前已經說完了,然后咱們再看分區索引

分區完了以后還得有分區索引,這是啥意思呢,就是你這個表分成了幾塊,假如你這個表,按照什么字段去分區的,相當于你把這個表分成了幾塊,分成1,2,3,4四塊,現在我要做什么事呢,我要在每一塊上,能不能建一個索引,分了區了查詢會很慢,首先你想一想,咱們這張表結構,我現在就模擬了兩個字段,我可能有很多的字段,ID當然是主鍵了這個沒法說,我現在是按照SALE_COUNT進行分區的,可能SALE_COUNT這個列,這個字段,按照這個列進行分區的,那么劃分成這四個區間以后,那我在這四個區域里,怎么去建索引呢,這個就相當于分區索引,分區以后雖然可以提高查詢效率,分區以后為什么提高查詢效率,其實它并不是提高了查詢效率,僅僅是提高了數據的范圍,那這個舉個列子吧,加入我這個表里面有8條數據,剛才我不是按照SALE_COUNT進行分區的嗎,可能把我這個分成了4個區間,分成1,2,3,4這四個區間,然后每個區間內分成兩個數據,如果我WHERE條件接的是一個SALE_COUNT,按照咱們剛才的說法,就是1000,然后這邊是1000到2000的,然后這邊是2000到3000的,然后這是maxvalue,那我現在想按照count去查詢,去查等于2300的,那這個是會提高查詢效率的,為什么呢,原先加入我不走索引,不走索引的字段,正常來講我是全表進行掃描,full-scan,都得從頭掃到尾,找到這兒,不是2300嗎,我在第三個區間,這個區間是2000到3000的區間,2000到3000區間的時候,才找到了這個數據,才知道2300,你得經歷查完這兩條,然后查完這兩條,才能查到第三個區間的這個數據,現在你做這個事情,都屏蔽掉了,P4也屏蔽掉了,直接到第三個區間,直接去找這個值,但是有一個問題是什么呢,你現在還是不是走索引,所以你要是分完區以后,加完這個索引,你這個效率才會變得很好,分區僅僅是縮小了查詢的范圍,咱們建立分區索引,進一步提高查詢效率,分區索引大體上分為兩類,一類叫做local,一類叫做global,一般我們都會使用本地的分區,在你建完分區的文件去建立索引,global就是不考慮分區,咱們還是在整個表去建立索引,你分不分區跟咱沒關系,我們一般采用本地模式,在每個分區上建立索引,說白了就是這個圖,我剛才使用SALE_COUNT進行分區的,我一定只能在SALE_COUNT這個分區字段上建立索引,只能在這個分區字段上建立索引,這個就是分區索引,它會子啊每一個LOCAL上建立索引,這塊是一塊區間,他建立了一個索引,這塊區間他也會建立一個索引,這塊區間,他也可會建立一個索引,相當于什么啊,相當于建立了4個索引,在一個字段上,但是是不同的區間,就是你執行這個語句之后,剛才這種方式叫做LOCAL,LOCAL的方式,還有一種方式叫做GLOBAL,GLOBAL的方式什么意思呢,就是不看這個分區了,反正我就建一把索引,在整體上去建索引的,要說的就是這個事,LOCAL是在每個分區上都建立索引,然后GLOBAL是在全局上去建立索引,這種方式其實和分不分區都是相同的,一般不使用,還有一種方式就是自定義數據區間的索引,這種索引可能叫做前綴索引,他不是按照區域去劃分的,但是他非常有意義,自定義區域值的時候必須要定義maxvalue,咱們先不考慮前綴索引了,咱們先說用得最多的LOCAL,在每個區間上加一個索引,然后你要注意的一點是什么啊,在分區字段上建的索引必須是分區字段上的列才行,也就是說咱們拿SALE這張表來舉列,加入現在PRODUCT_ID沒有建索引,就好像我這張表一樣,我這張表壓根就沒有去建這個INDEX,他也不是主鍵,有沒有去建INDEX,就是兩個平凡的字段,現在我想去建立索引,只能在分區字段上加索引,我只能在SALE_COUNT上加索引,這個就是開始就定死了的,你沒辦法,你沒辦法去做其他的事情,這種語法咱們看一下,create index indexName on table(field) local;其實就是在傳統的字段加一個local字段,建立索引你會了,無非就是后面加一個local,然后就完事了,其實分區索引,你要注意一個問題,第一分區上建立的索引,一定是分區字段,create index,這里面你隨便起個名字吧,我叫idx_count吧,然后你的table是SALE,然后field當然是SALE_COUNT,加了一個local就OKcreate index idx_count on SALE(SALE_COUNT) LOCAL;

你現在已經建立了分區索引了,就是這樣的,這個分區索引你現在也可以看到的,你也可以去查索引這張表,你也可以看到,SELECT * FROM USER_IND_PARTITION;

我現在這個名字叫做ind_count,它會產生三個,因為我現在只有三個分區,P1,P2,P3,我現在寫這一條SQL,相當于我寫這一條SQL語句,給我建立三個索引,在每個分區上建立一個索引,就是這個意思,全局的這種自定義索引,也是很有幫助的這是非常有意義的一種方式,這是啥意思呢,咱們之前都是很固化的,一個劃分,你比如說,1,2,3,4,這四塊,咱們剛才是按照COUNT,這個字段進行分區索引,在這里有個index,在這里有個index,假如有4個INDEX,但是這種只是LOCAL模式的分區索引,其實還有一種是前綴索引,前綴索引的意義就比較大了,他可以不考慮分區去建立索引,可以跨分區的去建立索引,比如說我可以去做什么事啊,原先是在在一個區間上去建立索引的,如果你有什么特殊的業務邏輯要求,咱們舉剛才那個例子,這個COUNT等于0到1000的范圍的數據,咱們會在第一個區間0到1000,第二個區間你是1000到2000的范圍,第三個區間是2000到3000,咱們就是舉個例子,比如3000到4000,就是只要你的COUNT是在這個區間范圍內,給你塞到指定的區間上,就是這個意思意思,但是現在有一個前綴索引,他可以不按照1,2,3,4區間去建索引,你比如說我現在就有個需求,我查詢比較頻繁的就是0到2300,0到2300的區間我查詢很頻繁,其他的我查詢不頻繁,那我建的這個索引就可以是這樣的,從這開始建,然后囊括了第二個,然后也囊括了第三個,但是囊括了第三個就是這樣的,然后這邊就給他排除,用紫色的排除,這里的數據肯定是0到1000,然后這里的數據是1000到2000,然后這塊的數據是2000到2300,然后這塊我刨除的是2300到3000,也就是2300到3000這塊我就不建索引了,那么我建的索引就是這塊,就是這個區域,我把這個刨除,摳出去了,那這種方式叫前綴索引,是根據你自己業務去做的,后期如果說你有這種業務,你需要跨分區的去建索引的話,其實還是非常有意義的,能理解我說的意思嗎,給我點反饋,如果是普通的表,那你沒辦法,那你建不了,就是這塊嗎,如果是一個普通的表,以后如果想去建分區怎么辦,那沒有任何的辦法,你只有一種辦法,什么辦法啊,你原先這個表里沒有建分區,這里邊有好多數據,你再克隆一張相同的表,先把這個分區劃分好,然后把這個數據導到這個分區里,你只有這一種辦法,能理解我說的意思吧,如果你表已經建好了,你就沒辦法再分區了,你只能再重新建立一張相同的表,然后咱們提前把分區建好,把之前的數據導入到新表,這才行,然后前綴索引怎么去建呢,create index 名字on table(field) global,global下面寫這個,partition by range(field),比較類似于咱們的分區了,在這里面又寫一個partition,寫你的值,你注意你必須得加上maxvalule才行,必須要指定maxvalue才行,就是無論你寫多少個,你得有一個maxvalue,就是你這里面可以有P1,P2,P3,P4,....,但是最終里面一定要有maxvalue,比如我是從0到1800,它是建立一個索引,然后從1800到2400,建立一個索引,然后從2400到1萬建立一個索引,但是最終總得有一個maxvalue才行,這是前綴索引建立的原則,必須得有他,要不然你這個東西是建立不成功的,還有這種全局索引的方式,create index idxname on table(field) global;這種方式不推薦,無非就是在普通的索引上,加了一個global,他和你平常在全表上建一個索引是一致的,是一樣的,其他字段不可以建索引,其實能建也是能建,可以去建這個索引,但是他效率一點也不高,所以我不推薦你去做這種事情,比如你現在硬要去寫,你現在想要去create index,然后在id上建一個索引,可以啊,但是他這個效率一點也都不會高,那你想想這不就是屬于全局索引嗎,就是一個global

?

總結

以上是生活随笔為你收集整理的Oracle之表分区、分区索引(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。