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/O和CPU資源選擇
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;
全局索引