oracle分區技術提高查詢效率
概述:
當表中的數據量不斷增大,查詢數據的速度就會變慢,應用程序的性能就會下降,這時就應該考慮對表進行分區。表進行分區後,邏輯上表仍然是一張完整的表,只是將表中的數據在物理上存放到多個表空間(物理文件上),這樣查詢數據時,不至於每次都掃描整張表。
下面介紹如何使用分區增加查詢效率
range分區:就是區域分區
CREATE TABLE SALE ( PRODUCT_ID VARCHAR2(5), SALE_COUNT NUMBER(10,2) ) PARTITION BY RANGE (SALE_COUNT) ( PARTITION P1 VALUESLESS THAN (1000) TABLESPACE CUS_TS01, PARTITION P2 VALUES LESS THAN (2000) TABLESPACE CUS_TS02 )
查看分區語法:
select * from user_tab_partitions; --查詢所有分區情況,可以接條件where table_name=‘sale‘查看分區表結構
select * from sale partition(p1); --查詢某表的某一分區數據
分區後,新增數據的SALE_COUNT字段如果小於1000就存儲到P1分區中,如果1000到2000存儲到P2分區中。
但是這時如果我們新增的一條數據的SALE_COUNT字段值大於2000,將無法存儲到表中。
我們可以擴展分區,語法如下:
alter table sale add partition p4 values less than(maxvalue); --大於2000的都會存到此分區中,當然也可以增加更多的分區
同時可以刪除分區,語法如下:
alter table sale drop partition p4; --註意:刪除分區會把分區內已有的數據同時刪除
但還存在一個問題,如果現在update分區p1中的SALE_COUNT值為1500,是不會成功的,需要在update前增加以下語句:
alter table sale enable row movement; --使其row能移動
這樣再update就可以成功了
分區索引
分區之後雖然可以提高查詢的效率,但也僅僅是提高了數據的範圍,所以我們在有必要的情況下,需要建立分區索引,從而進一步提高效率。
分區索引大體上分為兩大類,一類叫做local,一類叫做global。
local:在每個分區上建立索引(一般采用這種方式)
global:一種在全局上建立索引,這種方式分不分區都一樣,一般不使用
下面進行語法演示:
註意:分區上建立的索引一定是分區字段
create index idx_count on sale(sale_count) local;--建立分區索引,在sale表的每個分區都建立了索引
select * from user_ind_partitions;--查詢所有分區索引情況
全局索引global寫法就是把上面的local替換成global,但不會使用
有些時候,如果你分區分為0~1000,1000~2000,這時如果說0~1500這個範圍內的數據會被頻繁查詢,1500之後查詢很少,那麽就可以使用這種自定義的全局索引方式對0~1500建立索引,之後的設置maxvalue即可,語法與分區語法相似
global自定義全局索引方式(前綴索引):
create index idxname on table(field) global
partition by range(field)
(
partition p1 values less than(value), .......
partition pN values less than(maxvalue)
);
其他分區介紹
1.hash分區
hash分區實現均勻的負載值分配,增加hash分區可以重新分布數據,簡單理解就是分區直接平均分配
CREATE TABLE SALE ( PRODUCT_ID VARCHAR2(5), SALE_COUNT NUMBER(10,2) ) PARTITION BY HASH (PRODUCT_ID) ( PARTITION P1, PARTITION P2 )
2.list分區
該分區的特點是某列的值只有幾個,基於這樣的特點我們可以采用列表分區。
CREATE TABLE ListTable ( id INT PRIMARY KEY , name VARCHAR (20), area VARCHAR (10) ) PARTITION BY LIST (area) ( PARTITION part1 VALUES (‘guangdong‘,‘beijing‘) TABLESPACE Part1_tb, PARTITION part2 VALUES (‘shanghai‘,‘nanjing‘) TABLESPACE Part2_tb );
3.復合分區(用的不多)
create table student( sno number, sname varchar2(10) ) partition by range (sno) subpartition by hash (sname) subpartitions 4 ( partition p1 values less than(1000), partition p2 values less than(2000), partition p3 values less than(maxvalue) );
復合分區首先大體上分為三個分區p1,p2,p3,然後每一個分區內部再進行hash分區,分為4份
查詢子分區的語句:select * from user_tab_subpartitions where table_name=‘student‘;
4.間隔分區(工作中常用)
是一種分區自動化的分區,可以指定時間間隔進行分區,這是oracle11g的新特性,實際工作中很常用。實際上是由range分區引申的,最終實現了range分區的自動化
create table interval_sale (sid int,sdate timestamp) partition by range(sdate) interval (numtoyminterval(1,‘MONTH‘)) ( partition p1 values less than (TIMESTAMP ‘2017-11-12 00:00:00.00‘) )
指定時間之前建立一個分區,之後每隔一個月建立一個分區
問題:如果我們drop掉了表,那麽這個表的分區還存在嗎?
答案是存在的,oracle提供了很強大的數據恢復功能,有一個類似回收站的機制,刪除表後,分區以特殊的形式仍然存在user_tab_partitions中,使用purge recyclebin語法後,會清空回收站,使用flashback table 表名 to before drop語句可以恢復刪除的表。
oracle分區技術提高查詢效率