ORACLE表、索引和分區詳解

ORACLE表、索引和分區java

1、數據庫表sql

 每種類型的表都有不一樣的特性,分別應用與不一樣的領域數據庫

  堆組織表緩存

  聚簇表(共三種)session

  索引組織表數據結構

  嵌套表併發

  臨時表less

  外部表和對象表函數

1.行遷移高併發

建表過程當中能夠指定如下兩個參數:

   PCTFREE:自由空間,默認值10

  PCTUSED(只適用於MSSM):默認值40

設置這兩個參數很重要:

   一方面避免遷移過多的行,影響性能

   一方面避免浪費太多的空間 

當自由空間存不下更新後的某一行時,這一行將會發生行遷移,在兩個塊上存儲這一行數據,以下圖:

2.堆組織表

基本上咱們使用的表都是堆組織表(heap organized table),堆是無序的數據結構,數據的存取都是隨機的,想要排序必須使用order by子句

對於ASSM有三個重要的選項:

  PCTFREE

   INITRANS:默認值 2,高併發會設置更大一些 

  COMPRESS/NOCOMPRESS:啓用/禁用壓縮 

3.索引組織表(IOT

以索引結構存儲的表

使用場景:

  信息檢索

  空間數據

  OLAP應用

  建立,使用organization index子句:

create table tbl( name varchar2(20),  age int ) organization index

與堆組織表對比:

   提升緩衝區緩存效率,由於須要的塊更少

  減小緩衝區緩存訪問

  獲取數據快,工做量少

  完成查詢的物理I/O更少

  由於全部數據都放入索引,因此當表的數據量很大時,會下降索引組織表的查詢性能 

4.散列聚簇表

 

  散列聚簇表與索引聚簇表很是類似,一個主要區別就是:聚簇索引被一個散列函數所取代,表中的數據就是索引,散列聚簇表會預分配(hashkeys/trunc(blocksize/SIZE))個塊的存儲空間,SIZE爲設置的SIZE向上取最小的質數,hash衝突時會分配溢出塊與原來的塊鏈接起來

建立步驟:

  建立聚簇對象:create cluster hash_cluster(hash_key number) hashkeys 1000 size 1024;

   建立表: create table hash_table(x number, y varchar2(4000), z varchar2(400)) cluster hash_cluster(x);

注意:

  沒法對散列聚簇中的表進行區間掃描來定位數據,須要創建傳統索引實現

  創建散列聚簇表的目的是根據散列值快速定位數據,減小緩衝區緩存鏈閂,而不是平凡的全表掃描

  散列是CPU密集型操做,但索引所需的I/O會是散列的3倍,能夠根據I/OCPU資源選擇

5.有序散列聚簇表

有序散列聚簇不只有散列聚簇的特性,還結合了IOT的一些性質

場景:

  按照某個鍵查詢在按某一列排序

  select * from where key=:x order by sorted_column;

建立步驟:

  建立聚簇:create cluster shc(clust_id number, order_col number sort) hashkeys 100 hash is cust_id size 8192;

  建立表:create table cust_orders(clust_id number, order_col number, z varchar2(400)) cluster shc(clust_id, order_col);

6.對象表

一種基於Oracle類型的表

特色:

因爲對象表實際上就是假裝的關係表,這麼作與Oracle表功能沒什麼區別,但效率更高

建立:

create or replace type address_type as object(city varchar2(20), street varchar2(20));

create or replace type person_type as object(name varchar2(20), home_addr address_type, work_addr address_type);

create table people of person_type;

插入:

Insert into people values(‘ruphy’, address_type(‘gy’, ‘zunyi’), address_type(‘sz’, ‘bantian’));

查詢:

Select name, p.home_addr home, p.work_addr work from people p;

7.嵌套表

 

建立:

create or replace type emp_type as object(empno number, ename varchar2(40), job varchar(9));

create or replace type emp_tab_type as table or emp_type;--對象表

create table dept(deptno number primary key, dname varchar2(40), emps emp_tab_type);

查詢:

Select d.deptno, d.dname, emp.* from dept d, table(d.emps) emp;

插入:

Insert into table(select emps from dept where deptno = 10) values(123, ‘new’, ‘java’);

更新/刪除

update/delete table(select emps from dept where deptno = 10) set job = ‘C#’;

8.臨時表

可使用臨時表(temporary table)來保存事務或者會話內的臨時結果集

特色:

  隔離性

  無併發性問題

  靜態定義

  效率高,產生重作日誌少

  能夠有觸發器、檢查約束、索引,但不能有完整性約束、不能有嵌套列、不能是IOT、不能有聚簇、不能分區、不能使用analyze命令生成統計信息

類型:

  基於會話:create global temporary table temp_table_session on commit preserve rows ;

  基於事務:create global temporary table temp_table_session on commit delete rows ;

2、數據庫索引

最好在應用設計期間考慮索引應該如何設計,不要過後纔想起來,這樣有助於清楚地知道須要創建什麼樣的索引

Oracle提供幾種類型的索引:

  B*TREE索引

  T*TREE聚簇索引

  降序索引

  反向鍵索引

  IOT位圖索引

  位圖級聯索引

  函數索引

  應用域索引

1.B*TREE索引

--相似於二叉樹結構的索引,擴展性很是

 

分析一下幾種狀況:

  Where x between 20 and 30

  Where x = 10047

2.反向鍵索引
      --B*TREE索引鍵反轉創建的索引

主要用途是減小「右手」索引中索引頁塊的競爭

建立: create index idx on t(x,y) reverse;

分析一下幾種狀況:

  Where x > 5

  Where x = 5

3.降序索引
      --B*TREE索引擴展,以從大到小的方式存儲

主要用途是對多個列進行排序,且順序要求不一致時使用降序索引能夠避免數據庫額外的排序

建立:create index desc_t_idx on t(owner desc, object_type asc)

分析:select * from t where owner between ‘T’ and ‘Z’ order by owner desc, object_type asc;

4.何時走B*TREE索引

兩個「經驗」:

  訪問表中很是少的部分,到底多少與列數有關

  訪問表中大量數據時,數據能夠直接從索引中拿到(覆蓋索引)

5.位圖索引
      --位圖索引是爲數據倉庫/即席查詢設計

B*TREE索引不一樣,位圖索引的一個索引鍵會指向多行數據

位圖索引特別不適用於OLTP系統(平凡的更新)

建立:create bitmap index b_idx on t(owner);

位圖索引對or and not會執行位操做,存儲結構以下:

  

6.位圖級聯索引

在一個表上創建的索引基於另外一個表的列(主鍵或者惟一鍵),將數據在索引中逆規範化

場景:銷售部門多少人?誰在銷售部工做?銷售部業績最好的三我的?

建立:create bitmap index ed_idx on emp(d.dname) from emp e, dept d where  e.deptno = d.deptno

 

7.何時位圖索引

位圖索引特別適用於低基數(相異基數低)

相異基數大小取決於結果集行數,相異基數與總行數之比趨近與0纔算低相異基數,如2000行的表,相異基數爲3,那麼3/2000=0.0015很小,適合位圖索引

系統會運行大量的即席查詢,特別是查詢會使用多列數據或者使用諸如count之類的聚合函數

 

8.函數索引

能夠基於函數創建索引,本質上也是位圖索引或者B*TREE索引的擴展

使用場景:

  經過計算結果創建索引,方便須要使用函數計算後比叫時可以當即用上

  不用修改任何邏輯或查詢,就能夠加快現有應用

  只對感興趣的值鍵索引

建立:

create index f_idx on t(lower(owner));

create index f_idx on t(case owner when ‘PUBLIC’ then ‘PUBLIC’ end);

9.虛擬列索引

虛擬列

不佔用存儲過程,在查詢表數據時sql函數動態計算的返回值,不超過6398字節

建立:alter table t add cal as (lower(owner));

能夠在虛擬列創建一個索引,以提升查詢效率

建立: create index v_idx on t(cal);

10.組合索引

聯合索引時列的選擇原則

  最左匹配原則

  最左匹配原則

  最少空間原則

建立以下索引

  alter table T add constraint id_key primary key (OBJECT_ID);

  create index u_idx on t(upper(object_type), owner);

  create index f_idx on t(owner);

分析:

  Select * from t where object_id = 5;

  Select * from t where owner = ‘SYS’;

  Select * from t where object_type = ‘INDEX’;

  Select * from t where upper(object_type) = ‘INDEX’;

  Select * from t where upper(object_type) = ‘INDEX’ and owner = ‘SYS’;

  Select count(*) from t;

11.不走索引緣由

謂詞不在組合索引的最前列(最前列值比較少也會走索引)

Select count(*) from t;有索引但沒有索引列沒有非空約束

Select * from t where f(x) = :x;對非函數索引列使用了函數

Select * from t where y = 5; (y爲字符串)發生了隱式轉換

查詢的結果集超過了閾值

表上的統計信息不是最新的,dbms_stats.gather_table_stats(user, ‘T’);

將索引標記爲invisible

3、數據庫分區

分區將一個表或索引物理地分解爲多個更小、更易管理的部分,使用了一種「分而治之」的方法,設用於管理很是大的表

注意,分區不必定能提升性能,會產生三種狀況:

  應用可能運行更慢

  可能運行更快

  也可能沒有任何變化

1.分區的優點

提升數據可用性(獨立性)

將大段分解爲小段,從而減輕管理負擔

改善某些SQL語句(SIUD)性能性能(讀取信息語句、修改信息語句(PDML))

把數據修改分散,減小併發下系統的競爭

實現數據滑動窗口(去除舊數據,加載新數據並創建索引,將新數據歸入分區表)

2.分區機制

區間分區(範圍分區)

散列分區

列表分區

間隔分區:區間分區+自動建立分區

引用分區

間隔引用分區

虛擬列分區

組合分區

系統分區:比較少見

3.區間分區

建立:

create table range_t(range_key_column data not null, data varchar2(20)) partition by range(range_key_column)(partition part_1 values less than(to_date(‘20180101’, ‘yyyymmdd’)) ,partition part_2 values less than(to_date(‘20190101’, ‘yyyymmdd’)),partition part_3 values less(maxvalue));

4.散列分區

建立:

create table hash_t(range_key_column date, data varchar2(20)) partition by hash(range_key_column) (partition part_1 tablespace p1,partition part_2 tablespace p2);

5.列表分區

建立:

create table list_t(list_key_column varchar(2), data varchar2(20)) partition by list(list_key_column)(partition part_1 values('A', 'B'),partition part_2 values('C'));

6.虛擬列分區

建立:

create table res(res_code varchar(2), region as (decode(substr(res_code,1,1), 'A', 'NE', 'C', 'NE','B','SW','D','NW'))) partition by list(region)(partition p1 values('NE'), partition p2 values('SW'), partition p3 values('NW'));

7.組合分區

建立:

create table composite_t(range_c date, hash_c int, data varchar(2)) partition by range(range_c) interval (numtoyminterval(1, ‘year’)) subpartition by hash(hash_c) subpartitions 2 (partition p1 values less than(to_date(‘20180101’, ‘yyyymmdd’))(subpartition p1s1,subpartition p1s2), partition p2 values less than(to_date(‘20190101’, ‘yyyymmdd’))(subpartition p2s1,subpartition p2s2));

8.索引分區

 

本地索引:按表分區的方式對全部分區

  本地前綴索引

  本地非前綴索引

  建立: create index l_idx on t(owner, object_type) local;

全局分區索引:按區間或散列對索引分區

  建立:create index g_p_idx on t(owner, object_type, object_name) global partition by hash(owner) partitions 16;

全局索引

相關文章
相關標籤/搜索