深入學習Oracle分區表及分區索引
關于分區表和分區索引(About Partitioned Tables and Indexes)對于10gR2而言,基本上可以分成幾類:
• Range(范圍)分區
• Hash(哈希)分區
• List(列表)分區
• 以及組合分區:Range-Hash,Range-List。
對于表而言(常規意義上的堆組織表),上述分區形式都可以應用(甚至可以對某個分區指定compress屬性),只不過分區依賴列不能是lob,long之類數據類型,每個表的分區或子分區數的總數不能超過1023個。
對于索引組織表,只能夠支持普通分區方式,不支持組合分區,常規表的限制對于索引組織表同樣有效,除此之外呢,還有一些其實的限制,比如要求索引組織表的分區依賴列必須是主鍵才可以等。
注:本篇所有示例僅針對常規表,即堆組織表!
對于索引,需要區分創建的是全局索引,或本地索引:
l 全局索引(global index):即可以分區,也可以不分區。即可以建range分區,也可以建hash分區,即可建于分區表,又可創建于非分區表上,就是說,全局索引是完全獨立的,因此它也需要我們更多的維護操作。
l 本地索引(local index):其分區形式與表的分區完全相同,依賴列相同,存儲屬性也相同。對于本地索引,其索引分區的維護自動進行,就是說你add/drop/split/truncate表的分區時,本地索引會自動維護其索引分區。
Oracle建議如果單個表超過2G就最好對其進行分區,對于大表創建分區的好處是顯而易見的,這里不多論述why,而將重點放在when以及how。
ORACLE對于分區表方式其實就是將表分段存儲,一般普通表格是一個段存 儲,而分區表會分成多個段,所以查找數據過程都是先定位根據查詢條件定位分區范圍,即數據在那個分區或那幾個內部,然后在分區內部去查找數據,一個分區一 般保證四十多萬條數據就比較正常了,但是分區表并非亂建立,而其維護性也相對較為復雜一點,而索引的創建也是有點講究的,這些以下盡量闡述詳細即可。
range分區方式,也算是最常用的分區方式,其通過某字段或幾個字段的組合的值,從小到大,按照指定的范圍說明進行分區,我們在INSERT數據的時候就會存儲到指定的分區中。
List分區方式,一般是在range基礎上做的二級分區較多,是一種列舉方式進行分區,一般講某些地區、狀態或指定規則的編碼等進行劃分。
Hash分區方式,它沒有固定的規則,由ORACLE管理,只需要將值INSERT進去,ORACLE會自動去根據一套HASH算法去劃分分區,只需要告訴ORACLE要分幾個區即可。
WHEN
一、When使用Range分區
Range分區呢是應用范圍比較廣的表分區方式,它是以列的值的范圍來做為分區的劃分條件,將記錄存放到列值所在的range分區中,比如按照 時間劃分,2008年1季度的數據放到a分區,08年2季度的數據放到b分區,因此在創建的時候呢,需要你指定基于的列,以及分區的范圍值,如果某些記錄 暫無法預測范圍,可以創建maxvalue分區,所有不在指定范圍內的記錄都會被存儲到maxvalue所在分區中,并且支持指定多列做為依賴列,后面在 講how的時候會詳細談到。
二、When使用Hash分區
通常呢,對于那些無法有效劃分范圍的表,可以使用hash分區,這樣對于提高性能還是會有一定的幫助。hash分區會將表中的數據平均分配到你 指定的幾個分區中,列所在分區是依據分區列的hash值自動分配,因此你并不能控制也不知道哪條記錄會被放到哪個分區中,hash分區也可以支持多個依賴 列。
三、When使用List分區
List分區與range分區和hash分區都有類似之處,該分區與range分區類似的是也需要你指定列的值,但這又不同與range分區的 范圍式列值---其分區值必須明確指定,也不同與hash分區---通過明確指定分區值,你能控制記錄存儲在哪個分區。它的分區列只能有一個,而不能像 range或者hash分區那樣同時指定多個列做為分區依賴列,不過呢,它的單個分區對應值可以是多個。
你在分區時必須確定分區列可能存在的值,一旦插入的列值不在分區范圍內,則插入/更新就會失敗,因此通常建議使用list分區時,要創建一個default分區存儲那些不在指定范圍內的記錄,類似range分區中的maxvalue分區。
四、When使用組合分區
如果某表按照某列分區之后,仍然較大,或者是一些其它的需求,還可以通過分區內再建子分區的方式將分區再分區,即組合分區的方式。
組合分區呢在10g中有兩種:range-hash,range-list。注意順序喲,根分區只能是range分區,子分區可以是hash分區或list分區。
提示:11g在組合分區功能這塊有所增強,又推出了range-range,list-range,list-list,list-hash, 這就相當于除hash外三種分區方式的笛卡爾形式都有了。為什么會沒有hash做為根分區的組合分區形式呢,再仔細回味一下第二點,你一定能夠想明 白~~。
深入學習Oracle分區表及分區索引(2)
一、如何創建
如果想對某個表做分區,必須在創建表時就指定分區,我們可以對一個包含分區的表中的分區做修改,但不能直接將一個未分區的表修改成分區表(起碼在10g是不行的,當然你可能會說,可以通過在線重定義的方式,但是這不是直接喲,這也是借助臨時表間接實現的)。
創建表或索引的語法就不說了,大家肯定比我還熟悉,而想在建表(索引)同時指定分區也非常容易,只需要把創建分區的子句放到";"前就行啦,同 時需要注意表的row movement屬性,它用來控制是否允許修改列值所造成的記錄移動至其它分區存儲,有enable|disable兩種狀態,默認是disable row movement,當disable時,如果記錄要被更新至其它分區,則更新語句會報錯。
下面分別演示不同分區方式的表和索引的創建:
1、創建range分區
語法如下,需要我們指定的有:
l column:分區依賴列(如果是多個,以逗號分隔);
l partition:分區名稱;
l values less than:后跟分區范圍值(如果依賴列有多個,范圍對應值也應是多個,中間以逗號分隔);
l tablespace_clause:分區的存儲屬性,例如所在表空間等屬性(可為空),默認繼承基表所在表空間的屬性。
① 創建一個標準的range分區表:
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
);
表已創建。
要查詢創建分區的信息,可以通過查詢user_part_tables,user_tab_partitions兩個數據字典(索引分區、組織分區等信息也有對應的數據字典,后續示例會逐步提及)。
user_part_tables:記錄分區的表的信息;
user_tab_partitions:記錄表的分區的信息。
例如:
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;
② 創建global索引range分區:
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);
索引已創建。
由上例可以看出,創建global索引的分區與創建表的分區語句格式完全相同,而且其分區形式與索引所在表的分區形式沒有關聯關系。
注意:我們這里借助上面的表t_partition_range來演示創建range分區的global索引,并不表示range分區的表,只能創建range分區的global索引,只要你想,也可以為其創建hash分區的global索引。
查詢索引的分區信息可以通過user_part_indexes、user_ind_partitions兩個數據字典:
JSSWEB> select index_name, partitioning_type, partition_count
2 From user_part_indexes
3 where index_name = 'IDX_PARTI_RANGE_ID';
③ Local分區索引的創建最簡單,例如:
仍然借助t_partition_range表來創建索引
--首先刪除之前創建的global索引
JSSWEB> drop index IDX_PARTI_RANGE_ID;
索引已刪除。
JSSWEB> create index IDX_PARTI_RANGE_ID on T_PARTITION_RANGE(id) local;
索引已創建。
查詢相關數據字典:
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索引的分區完全繼承表的分區的屬性,包括分區類型,分區的范圍值即不需指定也不能更改,這就是前面說的:local索引的分區維護完全依賴于其索引所在表。
不過呢分區名稱,以及分區所在表空間等信息是可以自定義的,例如:
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 );
索引已創建。
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;
創建hash分區
語法如下:[圖:hash_partitioning.gif]
語法看起來比range復雜,其實使用起來比range更簡單,這里需要我們指定的有:
l column:分區依賴列(支持多個,中間以逗號分隔);
l partition:指定分區,有兩種方式:
n 直接指定分區名,分區所在表空間等信息
n 只指定分區數量,和可供使用的表空間。
2、創建hash分區
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);
表已創建。
要實現同樣效果,你還可以這樣:
JSSWEB> create table t_partition_hash2 (id number,name varchar2(50))
2 partition by hash(id)
3 partitions 3 store in(tbspart01,tbspart02,tbspart03);
表已創建。
這就是上面說的,直接指定分區數量和可供使用的表空間。
提示:這里分區數量和可供使用的表空間數量之間沒有直接對應關系。分區數并不一定要等于表空間數。
要查詢表的分區信息,仍然是通過user_part_tables,user_tab_partitions兩個數據字典,這里不再舉例。
① Global索引hash分區
Hash分區索引的子句與hash分區表的創建子句完全相同,例如:
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);
索引已創建。
查詢索引的分區信息也仍是通過user_part_indexes、user_ind_partitions兩個數據字典,不再舉例。
② 創建Local索引
在前面學習range分區時,我們已經對Local索引的特性做了非常清晰的概述,因此這里也不再舉例,如有疑問,建議再仔細復習range分區的相關示例,如果還有疑問,當面問我好了:)
綜上:
Ø 對于global索引分區而言,在10g中只能支持range分區和hash分區,因此后續示例中不會再提及。
Ø 對于local索引分區而言,其分區形式完全依賴于索引所在表的分區形式,不管從創建語法還是理解難度均無技術含量,因此后續也不再提供示例。
Ø 注意,在創建索引時如果不顯式指定global或local,則默認是global。
Ø 注意,在創建global索引時如果不顯式指定分區子句,則默認不分區(廢話)。
3、分區應用:
一般一張表超過2G的大小,ORACLE是推薦使用分區表的,分區一般都需要 創建索引,說到分區索引,就可以分為:全局索引、分區索引,即:global索引和local索引,前者為默認情況下在分區表上創建索引時的索引方式,并 不對索引進行分區(索引也是表結構,索引大了也需要分區,關于索引以后專門寫點)而全局索引可修飾為分區索引,但是和local索引有所區別,前者的分區 方式完全按照自定義方式去創建,和表結構完全無關,所以對于分區表的全局索引有以下兩幅網上常用的圖解:
3.1、對于分區表的不分區索引(這個有點繞,不過就是表分區,但其索引不分區):
創建語法(直接創建即可):
CREATE INDEX <index_name> ON <partition_table_name>(<column_name>);
3.2、對于分區表的分區索引:
創建語法為:
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索引結構:
創建語法為:
CREATE INDEX INX_TAB_PARTITION_COL1 ON TABLE_PARTITION(COL1) LOCAL;
也可按照分區表的的分區結構給與一一定義,索引的分區將得到重命名。
分區上的位圖索引只能為LOCAL索引,不能為GLOBAL全局索引。
3.4、對比索引方式:
一般使用LOCAL索引較為方便,而且維護代價較低,并且LOCAL索引是在分區的基礎上去創建索引,類似于在一個子表內部去創建索引,這樣開銷主要是區 分分區上,很規范的管理起來,在OLAP系統中應用很廣泛;而相對的GLOBAL索引是全局類型的索引,根據實際情況可以調整分區的類別,而并非按照分區 結構一一定義,相對維護代價較高一些,在OLTP環境用得相對較多,這里所謂OLTP和OLAP也是相對的,不是特殊的項目,沒有絕對的劃分概念,在應用 過程中依據實際情況而定,來提高整體的運行性能。
4、常用視圖:
1、查詢當前用戶下有哪些是分區表:
SELECT * FROM USER_PART_TABLES;
2、查詢當前用戶下有哪些分區索引:
SELECT * FROM USER_PART_INDEXES;
3、查詢當前用戶下分區索引的分區信息:
SELECT * FROM USER_IND_PARTITIONS T
WHERE T.INDEX_NAME=?
4、查詢當前用戶下分區表的分區信息:
SELECT * FROM USER_TAB_PARTITIONS T
WHERE T.TABLE_NAME=?;
5、查詢某分區下的數據量:
SELECT COUNT(*) FROM TABLE_PARTITION PARTITION(TAB_PARTOTION_01);
6、查詢索引、表上在那些列上創建了分區:
SELECT * FROM USER_PART_KEY_COLUMNS;
7、查詢某用戶下二級分區的信息(只有創建了二級分區才有數據):
SELECT * FROM USER_TAB_SUBPARTITIONS;
5、維護操作:
5.1、刪除分區
ALTER TABLE TABLE_PARTITION DROP PARTITION TAB_PARTOTION_03;
如果是全局索引,因為全局索引的分區結構和表可以不一致,若不一致的情況下,會導致整個全局索引失效,在刪除分區的時候,語句修改為:
ALTER TABLE TABLE_PARTITION DROP PARTITION TAB_PARTOTION_03 UPDATE GLOBAL INDEXES;
5.2、分區合并(從中間刪除掉一個分區,或者兩個分區需要合并后減少分區數量)
合并分區和刪除中間的RANGE有點像,但是合并分區是不會刪除數據的,對于LIST、HASH分區也是和RANGE分區不一樣的,其語法為:
ALTER TABLE TABLE_PARTITION MERGE PARTITIONS TAB_PARTOTION_01,TAB_PARTOTION_02 INTO PARTITION MERGED_PARTITION;
5.3、分隔分區(一般分區從擴展分區從分隔)
ALTER TABLE TABLE_PARTITION SPLIT PARTITION TAB_PARTOTION_OTHERE AT(2500000)
INTO (PARTITION TAB_PARTOTION_05,PARTITION TAB_PARTOTION_OTHERE);
5.4、創建新的分區(分區數據若不能提供范圍,則插入時會報錯,需要增加分區來擴大范圍)
一般有擴展分區的是都是用分隔的方式,若上述創建表時沒有創建TAB_PARTOTION_OTHER分區時,在插入數據較大時(按照上述建立規則,超過1800000就應該創建新的分區來存儲),就可以創建新的分區,如:
為了試驗,我們將擴展分區先刪除掉再創建新的分區(因為ORACLE要求,分區的數據不允許重疊,即按照分區字段同樣的數據不能同時存儲在不同的分區中):
ALTER TABLE TABLE_PARTITION DROP PARTITION TAB_PARTOTION_OTHER;
ALTER TABLE TABLE_PARTITION ADD PARTITION TAB_PARTOTION_06 VALUES LESS THAN(2500000);
在分區下創建新的子分區大致如下(RANGE分區,若為LIST或HASH分區,將創建方式修改為對應的方式即可):
ALTER TABLE <table_name> MODIFY PARTITION <partition_name> ADD SUBPARTITION <user_define_subpartition_name> VALUES LESS THAN(....);
5.5、修改分區名稱(修改相關的屬性信息)
ALTER TABLE TABLE_PARTITION RENAME PARTITION MERGED_PARTITION TO MERGED_PARTITION02;
5.6、交換分區(快速交換數據,其實是交換段名稱指針)
首先創建一個交換表,和原表結構相同,如果有數據,必須符合所交換對應分區的條件:
CREATE TABLE TABLE_PARTITION_2
AS SELECT * FROM TABLE_PARTITION WHERE 1=2;
然后將第一個分區的數據交換出去:
ALTER TABLE TABLE_PARTITION EXCHANGE PARTITION TAB_PARTOTION_01
WITH TABLE TABLE_PARTITION_2 INCLUDING INDEXES;
此時會發現第一個分區的數據和表TABLE_PARTITION_2做了瞬間交換,比TRUNCATE還要快,因為這個過程沒有進行數據轉存,只是段名稱的修改過程,和實際的數據量沒有關系。
如果是子分區也可以與外部的表進行交換,只需要將關鍵字修改為:SUBPARTITION 即可。
5.7、清空分區數據
ALTER TABLE <table_name> TRUNCATE PARTITION <partition_name>;
ALTER TABLE <table_name> TRUNCATE subpartition <subpartition_name>;
6、磁盤碎片壓縮
對分區表的某分區進行磁盤壓縮,當對分區內部數據進行了大量的UPDATE、DELETE操作后,一定時間需要進行磁盤壓縮,否則在查詢時,若通過FULL SCAN掃描數據,將會把空塊也會掃描到,對表進行磁盤壓縮需要進行行遷移操作,所以首先需要操作:
ALTER TABLE <table_name> ENABLE ROW MOVEMENT ;
對分區表的某分區壓縮語法為:
ALTER TABLE <table_name>
modify partition <partition_name> shrink space;
對普通表壓縮:
ALTER TABLE <table_name> shrink space;
對于索引也需要進行壓縮,索引也是表:
ALTER INDEX <index_name> shrink space;
7、分區表重新分析以及索引重新分析
對表進行壓縮后,需要對表和索引進行重新分析,對表進行重新分析,一般有兩種方式:
在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即可,不過一般比較常用的是重新編譯:
對于分區表并進行了索引分區的情況,需要對每個分區的索引進行重新編譯,這里以LOCAL索引為例子(其每個索引的分區和表分區結構相同,默認分區名稱和表分區名稱相同):
ALTER INDEX <index_name> REBUILD PARTITION <partition_name>;
對于全局索引,根據全局索引鎖定義的分區名稱修改即可,若沒有分區,和普通單表索引重新編譯方式相同:
ALTER INDEX <index_name> REBUILD;
1、關聯對象重新編譯
上述對表、索引進行重新編譯,尤其對表進行了壓縮后會產生行遷移,這個過程可能會導致一些視圖、過程對象的失效,此時要將其重新編譯一次。
2、擴展:HASH分區中,如果創建了新的分區,可以將其進行重新HASH分布:
ALTER TABLE <table_name> COALESCA PARTITION
8、回歸總結:何時建分區,分區類別,索引,如何對應SQL
1、創建時機
上述已經說明,2G以上的表,ORACLE推薦創建分區。
分區的方式根據實際情況而定,才能提高整體性能。
分區的字段一定要是經常用以提取數據的字段,否則會在提取過程中導致遍歷多個分區,這樣比沒有分區還要慢。
分區字段要選擇合適,數據較為均勻分布到各個分區,不要太多也不要太少,而且根據分區字段可以很快定位到分區范圍。
一般情況下,盡量然業務操作在同一個分區內部完成。
2、分區類別
分區主要有RANGE、LIST、HASH;
RANGE通過值的范圍分區,也是最常用的分區,這種分區注意在一種變長數字字符串中,很多人會導致認為是數字類型,而按照數字區分區,這樣會分布十分不均勻的現象發生。
LIST是列舉方式進行分區,一般作為二級分區而存在(當然也可以自己分區,ORACLE 11G后在分區上也可以作為主分區而存在),在RANGE基礎上,若數據需要繼續分區,并且在RANGE基礎上數據量較為固定,只是較大,可以按照一定規則進一步分區。
HASH只指定分區個數,分區細節由ORACLE完成,增加HASH分區可以重新分布數據。
注意:分區字段不能使用函數轉換后在分區,如,將某數字字符串字段,先TO_NUMER(COL_NAME)后分區。
3、索引類別
大致分:GLOBAL索引和LOCAL索引,錢和可以分:GLOBAL不分區索引,和GLOBAL分區索引。
GLOBAL不分區索引一般不太推薦,因為是用一顆大的索引樹來映射一個表,這個過程,這樣速度不見得比不分區快。
GLOBAL分區索引,查找數據若通過要通過索引,是先定位了索引內部的分區,然后在這個分區索引中找到ROWID,然后回表提取數據。
LOCAL索引是和分區的個數逐個對應的,可以說先定位分區表的分區也可以說先定位索引的分區,因為他們是一一對應的,找到對應分區后,分區內部索引數據集合。
4、對應應用
分區表、索引、分區索引,要利用其性能優勢,最基本就是要提取數據時,要通過它首先將數據的范圍縮小到一個即使做全盤掃描也不會太慢的情況。
所以SQL一定要有分區上的這個字段的一個WHERE條件,將數據迅速定位到分區內部,而且盡量定位到一個分區里面(這個和創建分區的規則有關系)。
建立分區本身不提要性能,要用好才可提高性能,在必要的RAC集群中,若存在多分區提取數據,適當采用并行提取可以提高提取的速度。
對于索引部分,這里也只提到分區索引的創建方式以及常見索引的維護方式,對于索引原理理解后會更容易認識到提取數據時的技巧。
9、實戰
分區表和一般表一樣可以建立索引,分區表可以創建局部索引和全局索引。當分區中出現許多事務并且要保證所有分區中的數據記錄的唯一性時采用全局索引。
1 局部索引分區的建立:
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>
看查詢的執行計劃,從下面的執行計劃可以看出,系統已經使用了索引:
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 全局索引分區的建立。
全局索引建立時global 子句允許指定索引的范圍值,這個范圍值為索引字段的范圍值:
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>
本例中對表的item_id字段建立索引分區,當然也可以不指定索引分區名直接對整個表建立索引,如:
SQL> create index dinya_idx_t on dinya_test(item_id);
Index created.
SQL>
同樣的,對全局索引根據執行計劃可以看出索引已經可以使用:
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>
其實分區的管理很簡單,難點在于分區方式的選擇和分區表上面索引的選擇。
Global Index全局索引和Local Index局部索引,Global partitioned index和global nonpartitioned index,
選擇多,就越迷惑。