Java世界

          學(xué)習(xí)筆記

          常用鏈接

          統(tǒng)計(jì)

          積分與排名

          天籟村

          新華網(wǎng)

          雅虎

          最新評(píng)論

          深入學(xué)習(xí)Oracle分區(qū)表及分區(qū)索引

          深入學(xué)習(xí)Oracle分區(qū)表及分區(qū)索引

           

          關(guān)于分區(qū)表和分區(qū)索引(About Partitioned Tables and Indexes)對(duì)于10gR2而言,基本上可以分成幾類(lèi):

          •          Range(范圍)分區(qū)

          •          Hash(哈希)分區(qū)

          •          List(列表)分區(qū)

          •          以及組合分區(qū):Range-Hash,Range-List。

            對(duì)于表而言(常規(guī)意義上的堆組織表),上述分區(qū)形式都可以應(yīng)用(甚至可以對(duì)某個(gè)分區(qū)指定compress屬性),只不過(guò)分區(qū)依賴列不能是lob,long之類(lèi)數(shù)據(jù)類(lèi)型,每個(gè)表的分區(qū)或子分區(qū)數(shù)的總數(shù)不能超過(guò)1023個(gè)。

            對(duì)于索引組織表,只能夠支持普通分區(qū)方式,不支持組合分區(qū),常規(guī)表的限制對(duì)于索引組織表同樣有效,除此之外呢,還有一些其實(shí)的限制,比如要求索引組織表的分區(qū)依賴列必須是主鍵才可以等。

            注:本篇所有示例僅針對(duì)常規(guī)表,即堆組織表!

            對(duì)于索引,需要區(qū)分創(chuàng)建的是全局索引,或本地索引:

            l 全局索引(global index):即可以分區(qū),也可以不分區(qū)。即可以建range分區(qū),也可以建hash分區(qū),即可建于分區(qū)表,又可創(chuàng)建于非分區(qū)表上,就是說(shuō),全局索引是完全獨(dú)立的,因此它也需要我們更多的維護(hù)操作。

            l 本地索引(local index):其分區(qū)形式與表的分區(qū)完全相同,依賴列相同,存儲(chǔ)屬性也相同。對(duì)于本地索引,其索引分區(qū)的維護(hù)自動(dòng)進(jìn)行,就是說(shuō)你add/drop/split/truncate表的分區(qū)時(shí),本地索引會(huì)自動(dòng)維護(hù)其索引分區(qū)。

          Oracle建議如果單個(gè)表超過(guò)2G就最好對(duì)其進(jìn)行分區(qū),對(duì)于大表創(chuàng)建分區(qū)的好處是顯而易見(jiàn)的,這里不多論述why,而將重點(diǎn)放在when以及how。

          ORACLE對(duì)于分區(qū)表方式其實(shí)就是將表分段存儲(chǔ),一般普通表格是一個(gè)段存 儲(chǔ),而分區(qū)表會(huì)分成多個(gè)段,所以查找數(shù)據(jù)過(guò)程都是先定位根據(jù)查詢條件定位分區(qū)范圍,即數(shù)據(jù)在那個(gè)分區(qū)或那幾個(gè)內(nèi)部,然后在分區(qū)內(nèi)部去查找數(shù)據(jù),一個(gè)分區(qū)一 般保證四十多萬(wàn)條數(shù)據(jù)就比較正常了,但是分區(qū)表并非亂建立,而其維護(hù)性也相對(duì)較為復(fù)雜一點(diǎn),而索引的創(chuàng)建也是有點(diǎn)講究的,這些以下盡量闡述詳細(xì)即可。

          range分區(qū)方式,也算是最常用的分區(qū)方式,其通過(guò)某字段或幾個(gè)字段的組合的值,從小到大,按照指定的范圍說(shuō)明進(jìn)行分區(qū),我們?cè)贗NSERT數(shù)據(jù)的時(shí)候就會(huì)存儲(chǔ)到指定的分區(qū)中。

          List分區(qū)方式,一般是在range基礎(chǔ)上做的二級(jí)分區(qū)較多,是一種列舉方式進(jìn)行分區(qū),一般講某些地區(qū)、狀態(tài)或指定規(guī)則的編碼等進(jìn)行劃分。

          Hash分區(qū)方式,它沒(méi)有固定的規(guī)則,由ORACLE管理,只需要將值INSERT進(jìn)去,ORACLE會(huì)自動(dòng)去根據(jù)一套HASH算法去劃分分區(qū),只需要告訴ORACLE要分幾個(gè)區(qū)即可。

          WHEN

            一、When使用Range分區(qū)

            Range分區(qū)呢是應(yīng)用范圍比較廣的表分區(qū)方式,它是以列的值的范圍來(lái)做為分區(qū)的劃分條件,將記錄存放到列值所在的range分區(qū)中,比如按照 時(shí)間劃分,2008年1季度的數(shù)據(jù)放到a分區(qū),08年2季度的數(shù)據(jù)放到b分區(qū),因此在創(chuàng)建的時(shí)候呢,需要你指定基于的列,以及分區(qū)的范圍值,如果某些記錄 暫無(wú)法預(yù)測(cè)范圍,可以創(chuàng)建maxvalue分區(qū),所有不在指定范圍內(nèi)的記錄都會(huì)被存儲(chǔ)到maxvalue所在分區(qū)中,并且支持指定多列做為依賴列,后面在 講how的時(shí)候會(huì)詳細(xì)談到。

            二、When使用Hash分區(qū)

            通常呢,對(duì)于那些無(wú)法有效劃分范圍的表,可以使用hash分區(qū),這樣對(duì)于提高性能還是會(huì)有一定的幫助。hash分區(qū)會(huì)將表中的數(shù)據(jù)平均分配到你 指定的幾個(gè)分區(qū)中,列所在分區(qū)是依據(jù)分區(qū)列的hash值自動(dòng)分配,因此你并不能控制也不知道哪條記錄會(huì)被放到哪個(gè)分區(qū)中,hash分區(qū)也可以支持多個(gè)依賴 列。

            三、When使用List分區(qū)

            List分區(qū)與range分區(qū)和hash分區(qū)都有類(lèi)似之處,該分區(qū)與range分區(qū)類(lèi)似的是也需要你指定列的值,但這又不同與range分區(qū)的 范圍式列值---其分區(qū)值必須明確指定,也不同與hash分區(qū)---通過(guò)明確指定分區(qū)值,你能控制記錄存儲(chǔ)在哪個(gè)分區(qū)。它的分區(qū)列只能有一個(gè),而不能像 range或者h(yuǎn)ash分區(qū)那樣同時(shí)指定多個(gè)列做為分區(qū)依賴列,不過(guò)呢,它的單個(gè)分區(qū)對(duì)應(yīng)值可以是多個(gè)。

            你在分區(qū)時(shí)必須確定分區(qū)列可能存在的值,一旦插入的列值不在分區(qū)范圍內(nèi),則插入/更新就會(huì)失敗,因此通常建議使用list分區(qū)時(shí),要?jiǎng)?chuàng)建一個(gè)default分區(qū)存儲(chǔ)那些不在指定范圍內(nèi)的記錄,類(lèi)似range分區(qū)中的maxvalue分區(qū)。

            四、When使用組合分區(qū)

            如果某表按照某列分區(qū)之后,仍然較大,或者是一些其它的需求,還可以通過(guò)分區(qū)內(nèi)再建子分區(qū)的方式將分區(qū)再分區(qū),即組合分區(qū)的方式。

            組合分區(qū)呢在10g中有兩種:range-hash,range-list。注意順序喲,根分區(qū)只能是range分區(qū),子分區(qū)可以是hash分區(qū)或list分區(qū)。

          提示:11g在組合分區(qū)功能這塊有所增強(qiáng),又推出了range-range,list-range,list-list,list-hash, 這就相當(dāng)于除hash外三種分區(qū)方式的笛卡爾形式都有了。為什么會(huì)沒(méi)有hash做為根分區(qū)的組合分區(qū)形式呢,再仔細(xì)回味一下第二點(diǎn),你一定能夠想明 白~~。

          深入學(xué)習(xí)Oracle分區(qū)表及分區(qū)索引(2)

          一、如何創(chuàng)建

            如果想對(duì)某個(gè)表做分區(qū),必須在創(chuàng)建表時(shí)就指定分區(qū),我們可以對(duì)一個(gè)包含分區(qū)的表中的分區(qū)做修改,但不能直接將一個(gè)未分區(qū)的表修改成分區(qū)表(起碼在10g是不行的,當(dāng)然你可能會(huì)說(shuō),可以通過(guò)在線重定義的方式,但是這不是直接喲,這也是借助臨時(shí)表間接實(shí)現(xiàn)的)。

            創(chuàng)建表或索引的語(yǔ)法就不說(shuō)了,大家肯定比我還熟悉,而想在建表(索引)同時(shí)指定分區(qū)也非常容易,只需要把創(chuàng)建分區(qū)的子句放到";"前就行啦,同 時(shí)需要注意表的row movement屬性,它用來(lái)控制是否允許修改列值所造成的記錄移動(dòng)至其它分區(qū)存儲(chǔ),有enable|disable兩種狀態(tài),默認(rèn)是disable row movement,當(dāng)disable時(shí),如果記錄要被更新至其它分區(qū),則更新語(yǔ)句會(huì)報(bào)錯(cuò)。

            下面分別演示不同分區(qū)方式的表和索引的創(chuàng)建:

          1、創(chuàng)建range分區(qū)

            語(yǔ)法如下,需要我們指定的有:

            l column:分區(qū)依賴列(如果是多個(gè),以逗號(hào)分隔);

            l partition:分區(qū)名稱(chēng);

            l values less than:后跟分區(qū)范圍值(如果依賴列有多個(gè),范圍對(duì)應(yīng)值也應(yīng)是多個(gè),中間以逗號(hào)分隔);

            l tablespace_clause:分區(qū)的存儲(chǔ)屬性,例如所在表空間等屬性(可為空),默認(rèn)繼承基表所在表空間的屬性。

          ① 創(chuàng)建一個(gè)標(biāo)準(zhǔn)的range分區(qū)表:

            JSSWEB> create table t_partition_range (id number,name varchar2(50))

              partition by range(id)(

              partition t_range_p1 values less than (10) tablespace tbspart01,

              partition t_range_p2 values less than (20) tablespace tbspart02,

              partition t_range_p3 values less than (30) tablespace tbspart03,

              partition t_range_pmax values less than (maxvalue) tablespace tbspart04

              );

            表已創(chuàng)建。

           要查詢創(chuàng)建分區(qū)的信息,可以通過(guò)查詢user_part_tables,user_tab_partitions兩個(gè)數(shù)據(jù)字典(索引分區(qū)、組織分區(qū)等信息也有對(duì)應(yīng)的數(shù)據(jù)字典,后續(xù)示例會(huì)逐步提及)。

            user_part_tables:記錄分區(qū)的表的信息;

            user_tab_partitions:記錄表的分區(qū)的信息。

            例如:

          JSSWEB> select table_name,partitioning_type,partition_count

                  From user_part_tables where table_name='T_PARTITION_RANGE';

          JSSWEB> select partition_name,high_value,tablespace_name

                 from user_tab_partitions where table_name='T_PARTITION_RANGE'

                 order by partition_position;

           

          ② 創(chuàng)建global索引range分區(qū):

            JSSWEB> create index idx_parti_range_id on t_partition_range(id)

            2 global partition by range(id)(

            3 partition i_range_p1 values less than (10) tablespace tbspart01,

            4 partition i_range_p2 values less than (40) tablespace tbspart02,

            5 partition i_range_pmax values less than (maxvalue) tablespace tbspart03);

            索引已創(chuàng)建。

            由上例可以看出,創(chuàng)建global索引的分區(qū)與創(chuàng)建表的分區(qū)語(yǔ)句格式完全相同,而且其分區(qū)形式與索引所在表的分區(qū)形式?jīng)]有關(guān)聯(lián)關(guān)系。

            注意:我們這里借助上面的表t_partition_range來(lái)演示創(chuàng)建range分區(qū)的global索引,并不表示range分區(qū)的表,只能創(chuàng)建range分區(qū)的global索引,只要你想,也可以為其創(chuàng)建hash分區(qū)的global索引。

            查詢索引的分區(qū)信息可以通過(guò)user_part_indexes、user_ind_partitions兩個(gè)數(shù)據(jù)字典:

          JSSWEB> select index_name, partitioning_type, partition_count

            2    From user_part_indexes

            3   where index_name = 'IDX_PARTI_RANGE_ID';

           

          ③ Local分區(qū)索引的創(chuàng)建最簡(jiǎn)單,例如:

            仍然借助t_partition_range表來(lái)創(chuàng)建索引

            --首先刪除之前創(chuàng)建的global索引

            JSSWEB> drop index IDX_PARTI_RANGE_ID;

            索引已刪除。

            JSSWEB> create index IDX_PARTI_RANGE_ID on T_PARTITION_RANGE(id) local;

            索引已創(chuàng)建。

            查詢相關(guān)數(shù)據(jù)字典:

          JSSWEB> select index_name, partitioning_type, partition_count

            2    From user_part_indexes

            3   where index_name = 'IDX_PARTI_RANGE_ID';

           

          JSSWEB> select partition_name, high_value, tablespace_name

            2    from user_ind_partitions

            3   where index_name = 'IDX_PARTI_RANGE_ID'

            4   order by partition_position;

           

           可以看出,local索引的分區(qū)完全繼承表的分區(qū)的屬性,包括分區(qū)類(lèi)型,分區(qū)的范圍值即不需指定也不能更改,這就是前面說(shuō)的:local索引的分區(qū)維護(hù)完全依賴于其索引所在表。

            不過(guò)呢分區(qū)名稱(chēng),以及分區(qū)所在表空間等信息是可以自定義的,例如:

            SQL> create index IDX_PART_RANGE_ID ON T_PARTITION_RANGE(id) local (

            2 partition i_range_p1 tablespace tbspart01,

            3 partition i_range_p2 tablespace tbspart01,

            4 partition i_range_p3 tablespace tbspart02,

            5 partition i_range_pmax tablespace tbspart02

            6 );

            索引已創(chuàng)建。

          SQL> select index_name, partitioning_type, partition_count

            2   From user_part_indexes

            3  where index_name = 'IDX_PART_RANGE_ID';

          SQL> select partition_name, high_value, tablespace_name

            2   from user_ind_partitions

            3  where index_name = 'IDX_PART_RANGE_ID'

            4  order by partition_position;

           創(chuàng)建hash分區(qū)

            語(yǔ)法如下:[圖:hash_partitioning.gif]

            

            語(yǔ)法看起來(lái)比range復(fù)雜,其實(shí)使用起來(lái)比range更簡(jiǎn)單,這里需要我們指定的有:

            l column:分區(qū)依賴列(支持多個(gè),中間以逗號(hào)分隔);

            l partition:指定分區(qū),有兩種方式:

            n 直接指定分區(qū)名,分區(qū)所在表空間等信息

          n 只指定分區(qū)數(shù)量,和可供使用的表空間。

           

          2、創(chuàng)建hash分區(qū)

            JSSWEB> create table t_partition_hash (id number,name varchar2(50))

            2 partition by hash(id)(

            3 partition t_hash_p1 tablespace tbspart01,

            4 partition t_hash_p2 tablespace tbspart02,

            5 partition t_hash_p3 tablespace tbspart03);

            表已創(chuàng)建。

            要實(shí)現(xiàn)同樣效果,你還可以這樣:

            JSSWEB> create table t_partition_hash2 (id number,name varchar2(50))

            2 partition by hash(id)

            3 partitions 3 store in(tbspart01,tbspart02,tbspart03);

            表已創(chuàng)建。

           這就是上面說(shuō)的,直接指定分區(qū)數(shù)量和可供使用的表空間。

            提示:這里分區(qū)數(shù)量和可供使用的表空間數(shù)量之間沒(méi)有直接對(duì)應(yīng)關(guān)系。分區(qū)數(shù)并不一定要等于表空間數(shù)。

          要查詢表的分區(qū)信息,仍然是通過(guò)user_part_tables,user_tab_partitions兩個(gè)數(shù)據(jù)字典,這里不再舉例。

           

           

          ① Global索引hash分區(qū)

            Hash分區(qū)索引的子句與hash分區(qū)表的創(chuàng)建子句完全相同,例如:

            JSSWEB> create index idx_part_hash_id on t_partition_hash(id)

            2 global partition by hash(id)

            3 partitions 3 store in(tbspart01,tbspart02,tbspart03);

            索引已創(chuàng)建。

            查詢索引的分區(qū)信息也仍是通過(guò)user_part_indexes、user_ind_partitions兩個(gè)數(shù)據(jù)字典,不再舉例。

          ② 創(chuàng)建Local索引

            在前面學(xué)習(xí)range分區(qū)時(shí),我們已經(jīng)對(duì)Local索引的特性做了非常清晰的概述,因此這里也不再舉例,如有疑問(wèn),建議再仔細(xì)復(fù)習(xí)range分區(qū)的相關(guān)示例,如果還有疑問(wèn),當(dāng)面問(wèn)我好了:)

            綜上:

            Ø 對(duì)于global索引分區(qū)而言,在10g中只能支持range分區(qū)和hash分區(qū),因此后續(xù)示例中不會(huì)再提及。

            Ø 對(duì)于local索引分區(qū)而言,其分區(qū)形式完全依賴于索引所在表的分區(qū)形式,不管從創(chuàng)建語(yǔ)法還是理解難度均無(wú)技術(shù)含量,因此后續(xù)也不再提供示例。

            Ø 注意,在創(chuàng)建索引時(shí)如果不顯式指定global或local,則默認(rèn)是global。

            Ø 注意,在創(chuàng)建global索引時(shí)如果不顯式指定分區(qū)子句,則默認(rèn)不分區(qū)(廢話)。

           

           

           

           

          3、分區(qū)應(yīng)用:

          一般一張表超過(guò)2G的大小,ORACLE是推薦使用分區(qū)表的,分區(qū)一般都需要 創(chuàng)建索引,說(shuō)到分區(qū)索引,就可以分為:全局索引、分區(qū)索引,即:global索引和local索引,前者為默認(rèn)情況下在分區(qū)表上創(chuàng)建索引時(shí)的索引方式,并 不對(duì)索引進(jìn)行分區(qū)(索引也是表結(jié)構(gòu),索引大了也需要分區(qū),關(guān)于索引以后專(zhuān)門(mén)寫(xiě)點(diǎn))而全局索引可修飾為分區(qū)索引,但是和local索引有所區(qū)別,前者的分區(qū) 方式完全按照自定義方式去創(chuàng)建,和表結(jié)構(gòu)完全無(wú)關(guān),所以對(duì)于分區(qū)表的全局索引有以下兩幅網(wǎng)上常用的圖解:

          3.1、對(duì)于分區(qū)表的不分區(qū)索引(這個(gè)有點(diǎn)繞,不過(guò)就是表分區(qū),但其索引不分區(qū)):

           

          創(chuàng)建語(yǔ)法(直接創(chuàng)建即可):

          CREATE INDEX <index_name> ON <partition_table_name>(<column_name>);

           

           

           

          3.2、對(duì)于分區(qū)表的分區(qū)索引:

           

          創(chuàng)建語(yǔ)法為:

          CREATE INDEX INX_TAB_PARTITION_COL1 ON TABLE_PARTITION(COL1)

            GLOBAL PARTITION BY RANGE(COL1)(

                   PARTITION IDX_P1 values less than (1000000),

                   PARTITION IDX_P2 values less than (2000000),

                   PARTITION IDX_P3 values less than (MAXVALUE)

            );

           

          3.3、LOCAL索引結(jié)構(gòu):

           

           

          創(chuàng)建語(yǔ)法為:

           CREATE INDEX INX_TAB_PARTITION_COL1 ON TABLE_PARTITION(COL1) LOCAL;

          也可按照分區(qū)表的的分區(qū)結(jié)構(gòu)給與一一定義,索引的分區(qū)將得到重命名。

          分區(qū)上的位圖索引只能為L(zhǎng)OCAL索引,不能為GLOBAL全局索引。

           

          3.4、對(duì)比索引方式:

           

            一般使用LOCAL索引較為方便,而且維護(hù)代價(jià)較低,并且LOCAL索引是在分區(qū)的基礎(chǔ)上去創(chuàng)建索引,類(lèi)似于在一個(gè)子表內(nèi)部去創(chuàng)建索引,這樣開(kāi)銷(xiāo)主要是區(qū) 分分區(qū)上,很規(guī)范的管理起來(lái),在OLAP系統(tǒng)中應(yīng)用很廣泛;而相對(duì)的GLOBAL索引是全局類(lèi)型的索引,根據(jù)實(shí)際情況可以調(diào)整分區(qū)的類(lèi)別,而并非按照分區(qū) 結(jié)構(gòu)一一定義,相對(duì)維護(hù)代價(jià)較高一些,在OLTP環(huán)境用得相對(duì)較多,這里所謂OLTP和OLAP也是相對(duì)的,不是特殊的項(xiàng)目,沒(méi)有絕對(duì)的劃分概念,在應(yīng)用 過(guò)程中依據(jù)實(shí)際情況而定,來(lái)提高整體的運(yùn)行性能。

           

          4、常用視圖:

          1、查詢當(dāng)前用戶下有哪些是分區(qū)表:

          SELECT * FROM USER_PART_TABLES;

           

          2、查詢當(dāng)前用戶下有哪些分區(qū)索引:

          SELECT * FROM USER_PART_INDEXES;

           

          3、查詢當(dāng)前用戶下分區(qū)索引的分區(qū)信息:

          SELECT * FROM USER_IND_PARTITIONS T

          WHERE T.INDEX_NAME=?

           

          4、查詢當(dāng)前用戶下分區(qū)表的分區(qū)信息:

          SELECT * FROM USER_TAB_PARTITIONS T

          WHERE T.TABLE_NAME=?;

           

          5、查詢某分區(qū)下的數(shù)據(jù)量:

          SELECT COUNT(*) FROM TABLE_PARTITION PARTITION(TAB_PARTOTION_01);

           

          6、查詢索引、表上在那些列上創(chuàng)建了分區(qū):

          SELECT * FROM USER_PART_KEY_COLUMNS;

           

          7、查詢某用戶下二級(jí)分區(qū)的信息(只有創(chuàng)建了二級(jí)分區(qū)才有數(shù)據(jù)):

          SELECT * FROM USER_TAB_SUBPARTITIONS;

           

          5、維護(hù)操作:

          5.1、刪除分區(qū)

              ALTER TABLE TABLE_PARTITION DROP PARTITION TAB_PARTOTION_03;

               如果是全局索引,因?yàn)槿炙饕姆謪^(qū)結(jié)構(gòu)和表可以不一致,若不一致的情況下,會(huì)導(dǎo)致整個(gè)全局索引失效,在刪除分區(qū)的時(shí)候,語(yǔ)句修改為:

               ALTER TABLE TABLE_PARTITION DROP PARTITION TAB_PARTOTION_03 UPDATE GLOBAL INDEXES;

           

          5.2、分區(qū)合并(從中間刪除掉一個(gè)分區(qū),或者兩個(gè)分區(qū)需要合并后減少分區(qū)數(shù)量)

              合并分區(qū)和刪除中間的RANGE有點(diǎn)像,但是合并分區(qū)是不會(huì)刪除數(shù)據(jù)的,對(duì)于LIST、HASH分區(qū)也是和RANGE分區(qū)不一樣的,其語(yǔ)法為:

          ALTER TABLE TABLE_PARTITION MERGE PARTITIONS    TAB_PARTOTION_01,TAB_PARTOTION_02 INTO PARTITION MERGED_PARTITION;

           

           

          5.3、分隔分區(qū)(一般分區(qū)從擴(kuò)展分區(qū)從分隔)

          ALTER TABLE TABLE_PARTITION SPLIT PARTITION TAB_PARTOTION_OTHERE AT(2500000)

          INTO (PARTITION TAB_PARTOTION_05,PARTITION TAB_PARTOTION_OTHERE);

           

          5.4、創(chuàng)建新的分區(qū)(分區(qū)數(shù)據(jù)若不能提供范圍,則插入時(shí)會(huì)報(bào)錯(cuò),需要增加分區(qū)來(lái)擴(kuò)大范圍)

          一般有擴(kuò)展分區(qū)的是都是用分隔的方式,若上述創(chuàng)建表時(shí)沒(méi)有創(chuàng)建TAB_PARTOTION_OTHER分區(qū)時(shí),在插入數(shù)據(jù)較大時(shí)(按照上述建立規(guī)則,超過(guò)1800000就應(yīng)該創(chuàng)建新的分區(qū)來(lái)存儲(chǔ)),就可以創(chuàng)建新的分區(qū),如:

          為了試驗(yàn),我們將擴(kuò)展分區(qū)先刪除掉再創(chuàng)建新的分區(qū)(因?yàn)镺RACLE要求,分區(qū)的數(shù)據(jù)不允許重疊,即按照分區(qū)字段同樣的數(shù)據(jù)不能同時(shí)存儲(chǔ)在不同的分區(qū)中):

          ALTER TABLE TABLE_PARTITION DROP PARTITION TAB_PARTOTION_OTHER;

          ALTER TABLE TABLE_PARTITION ADD PARTITION TAB_PARTOTION_06 VALUES LESS THAN(2500000);

           

          在分區(qū)下創(chuàng)建新的子分區(qū)大致如下(RANGE分區(qū),若為L(zhǎng)IST或HASH分區(qū),將創(chuàng)建方式修改為對(duì)應(yīng)的方式即可):

          ALTER TABLE <table_name> MODIFY PARTITION <partition_name> ADD SUBPARTITION <user_define_subpartition_name> VALUES LESS THAN(....);

           

          5.5、修改分區(qū)名稱(chēng)(修改相關(guān)的屬性信息)

          ALTER TABLE TABLE_PARTITION RENAME PARTITION MERGED_PARTITION TO MERGED_PARTITION02;

           

           

          5.6、交換分區(qū)(快速交換數(shù)據(jù),其實(shí)是交換段名稱(chēng)指針)

            首先創(chuàng)建一個(gè)交換表,和原表結(jié)構(gòu)相同,如果有數(shù)據(jù),必須符合所交換對(duì)應(yīng)分區(qū)的條件:

            CREATE TABLE TABLE_PARTITION_2

            AS SELECT * FROM TABLE_PARTITION WHERE 1=2;

            然后將第一個(gè)分區(qū)的數(shù)據(jù)交換出去:

            ALTER TABLE TABLE_PARTITION EXCHANGE PARTITION TAB_PARTOTION_01

            WITH TABLE TABLE_PARTITION_2 INCLUDING INDEXES;

            此時(shí)會(huì)發(fā)現(xiàn)第一個(gè)分區(qū)的數(shù)據(jù)和表TABLE_PARTITION_2做了瞬間交換,比TRUNCATE還要快,因?yàn)檫@個(gè)過(guò)程沒(méi)有進(jìn)行數(shù)據(jù)轉(zhuǎn)存,只是段名稱(chēng)的修改過(guò)程,和實(shí)際的數(shù)據(jù)量沒(méi)有關(guān)系。

           

            如果是子分區(qū)也可以與外部的表進(jìn)行交換,只需要將關(guān)鍵字修改為:SUBPARTITION 即可。

           

          5.7、清空分區(qū)數(shù)據(jù)

           

             ALTER TABLE <table_name> TRUNCATE PARTITION <partition_name>;

             ALTER TABLE <table_name> TRUNCATE subpartition <subpartition_name>;

           

          6、磁盤(pán)碎片壓縮

             對(duì)分區(qū)表的某分區(qū)進(jìn)行磁盤(pán)壓縮,當(dāng)對(duì)分區(qū)內(nèi)部數(shù)據(jù)進(jìn)行了大量的UPDATE、DELETE操作后,一定時(shí)間需要進(jìn)行磁盤(pán)壓縮,否則在查詢時(shí),若通過(guò)FULL SCAN掃描數(shù)據(jù),將會(huì)把空塊也會(huì)掃描到,對(duì)表進(jìn)行磁盤(pán)壓縮需要進(jìn)行行遷移操作,所以首先需要操作:

          ALTER TABLE <table_name> ENABLE ROW MOVEMENT ;

           

              對(duì)分區(qū)表的某分區(qū)壓縮語(yǔ)法為:

          ALTER TABLE <table_name>

          modify partition <partition_name> shrink space;

             對(duì)普通表壓縮:

          ALTER TABLE <table_name> shrink space;

            對(duì)于索引也需要進(jìn)行壓縮,索引也是表:

          ALTER INDEX <index_name> shrink space;

           

           

          7、分區(qū)表重新分析以及索引重新分析

            對(duì)表進(jìn)行壓縮后,需要對(duì)表和索引進(jìn)行重新分析,對(duì)表進(jìn)行重新分析,一般有兩種方式:

            在ORACLE 10G以前,使用:

            BEGIN

               dbms_stats.gather_table_stats(USER,UPPER('<table_name>'));

            END;

           

            ORACLE 10G后,可以使用:

            ANALYZE TABLE <table_name> COMPUTE STATISTICS;

           

            索引重新分析,將上述兩種方式分別修改一下,如第一種可以使用:gather_index_stats,而第二種修改為:ANALYZE INDEX即可,不過(guò)一般比較常用的是重新編譯:

            對(duì)于分區(qū)表并進(jìn)行了索引分區(qū)的情況,需要對(duì)每個(gè)分區(qū)的索引進(jìn)行重新編譯,這里以LOCAL索引為例子(其每個(gè)索引的分區(qū)和表分區(qū)結(jié)構(gòu)相同,默認(rèn)分區(qū)名稱(chēng)和表分區(qū)名稱(chēng)相同):

           ALTER INDEX <index_name> REBUILD PARTITION <partition_name>;

            對(duì)于全局索引,根據(jù)全局索引鎖定義的分區(qū)名稱(chēng)修改即可,若沒(méi)有分區(qū),和普通單表索引重新編譯方式相同:

           ALTER INDEX <index_name> REBUILD;

           

          1、關(guān)聯(lián)對(duì)象重新編譯

            上述對(duì)表、索引進(jìn)行重新編譯,尤其對(duì)表進(jìn)行了壓縮后會(huì)產(chǎn)生行遷移,這個(gè)過(guò)程可能會(huì)導(dǎo)致一些視圖、過(guò)程對(duì)象的失效,此時(shí)要將其重新編譯一次。

           

           

          2、擴(kuò)展:HASH分區(qū)中,如果創(chuàng)建了新的分區(qū),可以將其進(jìn)行重新HASH分布:

          ALTER TABLE <table_name> COALESCA PARTITION

           

           

          8、回歸總結(jié):何時(shí)建分區(qū),分區(qū)類(lèi)別,索引,如何對(duì)應(yīng)SQL

           

          1、創(chuàng)建時(shí)機(jī)

           

               上述已經(jīng)說(shuō)明,2G以上的表,ORACLE推薦創(chuàng)建分區(qū)。

               分區(qū)的方式根據(jù)實(shí)際情況而定,才能提高整體性能。

               分區(qū)的字段一定要是經(jīng)常用以提取數(shù)據(jù)的字段,否則會(huì)在提取過(guò)程中導(dǎo)致遍歷多個(gè)分區(qū),這樣比沒(méi)有分區(qū)還要慢。

               分區(qū)字段要選擇合適,數(shù)據(jù)較為均勻分布到各個(gè)分區(qū),不要太多也不要太少,而且根據(jù)分區(qū)字段可以很快定位到分區(qū)范圍。

               一般情況下,盡量然業(yè)務(wù)操作在同一個(gè)分區(qū)內(nèi)部完成。

           

           

          2、分區(qū)類(lèi)別

           

              分區(qū)主要有RANGE、LIST、HASH;

               RANGE通過(guò)值的范圍分區(qū),也是最常用的分區(qū),這種分區(qū)注意在一種變長(zhǎng)數(shù)字字符串中,很多人會(huì)導(dǎo)致認(rèn)為是數(shù)字類(lèi)型,而按照數(shù)字區(qū)分區(qū),這樣會(huì)分布十分不均勻的現(xiàn)象發(fā)生。

               LIST是列舉方式進(jìn)行分區(qū),一般作為二級(jí)分區(qū)而存在(當(dāng)然也可以自己分區(qū),ORACLE 11G后在分區(qū)上也可以作為主分區(qū)而存在),在RANGE基礎(chǔ)上,若數(shù)據(jù)需要繼續(xù)分區(qū),并且在RANGE基礎(chǔ)上數(shù)據(jù)量較為固定,只是較大,可以按照一定規(guī)則進(jìn)一步分區(qū)。

               HASH只指定分區(qū)個(gè)數(shù),分區(qū)細(xì)節(jié)由ORACLE完成,增加HASH分區(qū)可以重新分布數(shù)據(jù)。

           

               注意:分區(qū)字段不能使用函數(shù)轉(zhuǎn)換后在分區(qū),如,將某數(shù)字字符串字段,先TO_NUMER(COL_NAME)后分區(qū)。

           

          3、索引類(lèi)別

              大致分:GLOBAL索引和LOCAL索引,錢(qián)和可以分:GLOBAL不分區(qū)索引,和GLOBAL分區(qū)索引。

           

               GLOBAL不分區(qū)索引一般不太推薦,因?yàn)槭怯靡活w大的索引樹(shù)來(lái)映射一個(gè)表,這個(gè)過(guò)程,這樣速度不見(jiàn)得比不分區(qū)快。

               GLOBAL分區(qū)索引,查找數(shù)據(jù)若通過(guò)要通過(guò)索引,是先定位了索引內(nèi)部的分區(qū),然后在這個(gè)分區(qū)索引中找到ROWID,然后回表提取數(shù)據(jù)。

               LOCAL索引是和分區(qū)的個(gè)數(shù)逐個(gè)對(duì)應(yīng)的,可以說(shuō)先定位分區(qū)表的分區(qū)也可以說(shuō)先定位索引的分區(qū),因?yàn)樗麄兪且灰粚?duì)應(yīng)的,找到對(duì)應(yīng)分區(qū)后,分區(qū)內(nèi)部索引數(shù)據(jù)集合。

           

          4、對(duì)應(yīng)應(yīng)用

               分區(qū)表、索引、分區(qū)索引,要利用其性能優(yōu)勢(shì),最基本就是要提取數(shù)據(jù)時(shí),要通過(guò)它首先將數(shù)據(jù)的范圍縮小到一個(gè)即使做全盤(pán)掃描也不會(huì)太慢的情況。

                所以SQL一定要有分區(qū)上的這個(gè)字段的一個(gè)WHERE條件,將數(shù)據(jù)迅速定位到分區(qū)內(nèi)部,而且盡量定位到一個(gè)分區(qū)里面(這個(gè)和創(chuàng)建分區(qū)的規(guī)則有關(guān)系)。

                建立分區(qū)本身不提要性能,要用好才可提高性能,在必要的RAC集群中,若存在多分區(qū)提取數(shù)據(jù),適當(dāng)采用并行提取可以提高提取的速度。

                對(duì)于索引部分,這里也只提到分區(qū)索引的創(chuàng)建方式以及常見(jiàn)索引的維護(hù)方式,對(duì)于索引原理理解后會(huì)更容易認(rèn)識(shí)到提取數(shù)據(jù)時(shí)的技巧。

           

          9、實(shí)戰(zhàn)

           

          分區(qū)表和一般表一樣可以建立索引,分區(qū)表可以創(chuàng)建局部索引和全局索引。當(dāng)分區(qū)中出現(xiàn)許多事務(wù)并且要保證所有分區(qū)中的數(shù)據(jù)記錄的唯一性時(shí)采用全局索引。

          1 局部索引分區(qū)的建立:

          SQL> create index dinya_idx_t on dinya_test(item_id)

            2  local

            3  (

            4     partition idx_1 tablespace dinya_space01,

            5     partition idx_2 tablespace dinya_space02,

            6     partition idx_3 tablespace dinya_space03

            7  );

           

          Index created.

           

          SQL>

           

           

          看查詢的執(zhí)行計(jì)劃,從下面的執(zhí)行計(jì)劃可以看出,系統(tǒng)已經(jīng)使用了索引:

          SQL> select * from dinya_test partition(part_01) t where t.item_id=12;

           

          Execution Plan

          ----------------------------------------------------------

             0      SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=187)

             1    0   TABLE ACCESS (BY LOCAL INDEX ROWID) OF 'DINYA_TEST' (Cost=

                    2 Card=1 Bytes=187)

             2    1     INDEX (RANGE SCAN) OF 'DINYA_IDX_T' (NON-UNIQUE) (Cost=1

                     Card=1)

          Statistics

          ----------------------------------------------------------

                    0  recursive calls

                    0  db block gets

                    4  consistent gets

                    0  physical reads

                    0  redo size

                  334  bytes sent via SQL*Net to client

                  309  bytes received via SQL*Net from client

                    2  SQL*Net roundtrips to/from client

                    1  sorts (memory)

                    0  sorts (disk)

                    2  rows processed

           

          SQL>

           

          2 全局索引分區(qū)的建立。

          全局索引建立時(shí)global 子句允許指定索引的范圍值,這個(gè)范圍值為索引字段的范圍值:

          SQL> create index dinya_idx_t on dinya_test(item_id)

            2  global partition by range(item_id)

            3  (

            4     partition idx_1 values less than (1000) tablespace dinya_space01,

            5     partition idx_2 values less than (10000) tablespace dinya_space02,

            6     partition idx_3 values less than (maxvalue) tablespace dinya_space03

            7  );

           

          Index created.

           

          SQL>

           

           

          本例中對(duì)表的item_id字段建立索引分區(qū),當(dāng)然也可以不指定索引分區(qū)名直接對(duì)整個(gè)表建立索引,如:

          SQL> create index dinya_idx_t on dinya_test(item_id);

          Index created.

           

          SQL>

           

           

          同樣的,對(duì)全局索引根據(jù)執(zhí)行計(jì)劃可以看出索引已經(jīng)可以使用:

          SQL> select * from dinya_test t where t.item_id=12;

           

          Execution Plan

          ----------------------------------------------------------

             0      SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=3 Bytes=561)

             1    0   TABLE ACCESS (BY GLOBAL INDEX ROWID) OF 'DINYA_TEST' (Cost

                    =2 Card=3 Bytes=561)

           

             2    1     INDEX (RANGE SCAN) OF 'DINYA_IDX_T' (NON-UNIQUE) (Cost=1

                     Card=3)

          Statistics

          ----------------------------------------------------------

                    5  recursive calls

                    0  db block gets

                   10  consistent gets

                    0  physical reads

                    0  redo size

                  420  bytes sent via SQL*Net to client

                  309  bytes received via SQL*Net from client

                    2  SQL*Net roundtrips to/from client

                    3  sorts (memory)

                    0  sorts (disk)

                    5  rows processed

           

          SQL>

           

           

          其實(shí)分區(qū)的管理很簡(jiǎn)單,難點(diǎn)在于分區(qū)方式的選擇和分區(qū)表上面索引的選擇。  

          Global Index全局索引和Local Index局部索引,Global partitioned index和global nonpartitioned index,

          選擇多,就越迷惑。

          posted on 2013-01-08 15:26 Rabbit 閱讀(46704) 評(píng)論(1)  編輯  收藏

          評(píng)論

          # re: 深入學(xué)習(xí)Oracle分區(qū)表及分區(qū)索引[未登錄](méi) 2014-12-17 11:05 ray

          3KS  回復(fù)  更多評(píng)論   


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 吉林省| 屯门区| 宣威市| 公主岭市| 桂东县| 定南县| 额济纳旗| 宜兴市| 甘孜县| 朝阳市| 内黄县| 贺兰县| 甘谷县| 托克逊县| 邹城市| 定安县| 墨脱县| 德格县| 乐安县| 鄂尔多斯市| 康平县| 巴彦县| 班玛县| 紫金县| 乌拉特后旗| 衡阳县| 迁安市| 永城市| 孝义市| 乐业县| 墨江| 高陵县| 平顺县| 驻马店市| 定结县| 壶关县| 杭锦后旗| 偃师市| 濮阳市| 珠海市| 嘉义市|