ORACLE 表类型 OLTP和OLAP
生活随笔
收集整理的這篇文章主要介紹了
ORACLE 表类型 OLTP和OLAP
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
表類型?
1、表的功能:存儲、管理數據的基本單元(二維表:有行和列組成) 2、表的類型:1)堆表:heap table :數據存儲時,行是無序的,對它的訪問采用全表掃描。2)分區表 表>2G3)索引組織表(IOT)4)簇表5)臨時表6)壓縮表7)嵌套表3、如何將普通表轉換為分區表;11g以前,1)create 分區表, 2)insert into 分區表 select * from 普通表; 3)rename 分區表名; 4)重建約束、索引、觸發器。11g以后,在線重定義分區表12.1 分區表及其種類(10g)1)Range Partitioning (范圍分區)scott:SQL>create table sale( product_id varchar2(5), sales_count number(10,2) ) partition by range(sales_count) (partition p1 values less than(1000),partition p2 values less than(2000),partition p3 values less than(3000) ); 查看信息:select * from user_tab_partitions where table_name='SALE';?insert into sale values('1',600); insert into sale values('2',1000); insert into sale values('3',2300); insert into sale values('4',6000); commit;select * from sale partition(p1); select * from sale partition(p2);增加一個分區 alter table sale add partition p4 values less than(maxvalue);再看一下, 可以插入6000值了 select * from user_tab_partitions where table_name='SALE'; insert into sale values('4',6000);看一下段的分配 SQL> select segment_name,segment_type,partition_name from user_segments;12.1.1 默認情況下,如果對分區表的分區字段做超范圍(跨段)update操作,會報錯——ORA-14402: 。如果一定要改,可以通過打開表的row movement屬性來完成。SQL> select rowid,t1.* from sale partition(p1) t1;ROWID ? ? ? ? ? ? ?PRODU SALES_COUNT ------------------ ----- ----------- AAASvUAAEAAAAGVAAA 1 ? ? ? ? ? ? 600SQL> update sale set sales_count=1200 where sales_count=600; update sale set sales_count=1200 where sales_count=600* 第 1 行出現錯誤: ORA-14402: 更新分區關鍵字列將導致分區的更改SQL> alter table sale enable row movement; SQL> update sale set sales_count=1200 where sales_count=600;已更新 1 行。SQL> select rowid,t1.* from sale partition(p2) t1;ROWID ? ? ? ? ? ? ?PRODU SALES_COUNT ------------------ ----- ----------- AAASvVAAEAAAAGdAAA 2 ? ? ? ? ? ?1000 AAASvVAAEAAAAGdAAB 1 ? ? ? ? ? ?1200一般來說范圍分區的分區字段使用數字類型或日期類型,使用字符類型的語法是可以的,實際工作中使用較少。這或許跟values less than 子句有關。12.1.2 關于建立分區索引一般使用分區都會建立索引,分區索引有local與global之分。Local Parfixed Index|-----------------------------Local Partitioned Index ? | |-----------------------------|Partitioned Index ? ? ? ? ? ? ? ? ? ?| ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |Local Nonparfixed Index |----------------------------------| ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |------------------------------ | ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| | |Global Partitioned Index | |------------------------------ | |Nonpartitioned Index? |------------------------1)local:一個索引分區對應一個表分區,分區key就是索引key,分區邊界就是索引邊界。更新一個表分區時僅僅影響該分區的索引。SQL>create index sale_idx on sale(sales_count) local; SQL>select * from user_ind_partitions;Local Parfixed Index,所謂前綴索引,是指組合索引中的first column使用的是分區key。?global:全局索引:2)分區全局索引:索引分區不與表分區對應,分區key是索引key。另外一定要將maxvalue關鍵字做上限。 create index sale_global_idx on sale(sales_count) global partition by range (sales_count) ( partition p1 values less than(1500), partition p2 values less than(maxvalue) );SQL>select * from user_ind_partitions;?12.1.3 刪除一個分區,其中的數據全部清除,并且包括相關索引等 SQL> alter table sale drop partition p3;12.1.4 Hash Partitioning (散列分區,也叫hash分區)?實現均勻的負載值分配,增加HASH分區可以重新分布數據。create table my_emp(empno number, ename varchar2(10) ) partition by hash(empno)? (partition p1, partition p2 );select * from user_tab_partitions where table_name='MY_EMP';插入幾個值,看是否均勻插入。insert into my_emp values(1,'A'); insert into my_emp values(2,'B'); insert into my_emp values(3,'C');select * from my_emp partition(P1); select * from my_emp partition(P2);12.1.5 列表分區(list): 將不相關的數據組織在一起create table personcity(id number, name varchar2(10), city varchar2(10) ) partition by list(city) (partition east values('tianjin','dalian'),partition west values('xian'),partition south values ('shanghai'),partition north values ('herbin'),partition other values (default) );insert into personcity values(1,'sohu','tianjin'); insert into personcity values(2,'sina','herbin'); insert into personcity values(3,'yahoo','dalian'); insert into personcity values(4,'360','zhengzhou'); insert into personcity values(5,'baidu','xian');看結果select * from personcity partition(east);12.1.6 Composite Partitioning(復合分區)把范圍分區和散列分區相結合或者 范圍分區和列表分區相結合。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) );有三個range分區,對每個分區會有4個hash分區,共有12個分區。SQL> select * from user_tab_partitions where table_name='STUDENT';SQL> select * from user_tab_subpartitions where table_name='STUDENT';用EM查看,看scott的student table子分區里的名字是由oracle取名。12.2 Oracle11g新增分區Partition(分區),一直是Oracle數據庫引以為榮的一項技術,正是分區的存在讓Oracle高效的處理海量數據成為可能。在Oracle11g在 10g的分區技術基礎上又有了新的發展,使分區技術在易用性和可擴展性上再次得到了增強。12.2.1 Interval Partitioning (間隔分區)實際上是由range分區引申而來,最終實現了range分區的自動化。 scott: SQL> create table interval_sales (s_id int,d_1 date) partition by range(d_1) interval (numtoyminterval(1,'MONTH')) (partition p1 values less than ( to_date('2010-02-01','yyyy-mm-dd') ) );SQL> insert into interval_sales values(1, to_date('2010-01-21','yyyy-mm-dd') ); SQL> insert into interval_sales values(2, to_date('2010-02-01','yyyy-mm-dd') );--越過p1分區上線,將自動建立一個分區 SQL> select partition_name from user_tab_partitions;PARTITION_NAME ------------------------------ P1 SYS_P61注意:interval (numtoyminterval(1,'MONTH'))的意思就是每個月有一個分區,每當輸入了新的月份的數據,這個分區就會自動建立,而 不同年的相同月份是兩個分區。12.2.2 System Partitioning (系統分區)這是一個人性化的分區類型,System Partitioning,在這個新的類型中,不需要指定任何分區鍵,數據會進入哪個分區完全由應用程序決 定,即在Insert語句中決定記錄行插入到哪個分區。先建立三個表空間 tbs1,tbs2,tbs3, 然后建立三個分區的system分區表,分布在三個表空間上。create table test (c1 int,c2 int) partition by system (partition p1 tablespace tbs1,partition p2 tablespace tbs2,partition p3 tablespace tbs3 );現在由SQL語句來指定插入哪個分區:SQL> INSERT INTO test PARTITION (p1) VALUES (1,3); SQL> INSERT INTO test PARTITION (p3) VALUES (4,5);SQL> select * from test;C1 ? ? ? ? C2 ---------- ----------1 ? ? ? ? ?34 ? ? ? ? ?5注意:如果要刪除以上表空間,必須先刪除其上的分區表,否則會報錯ORA-14404: 分區表包含不同表空間中的分區。12.2.3 Reference Partitioning (引用分區)當兩個表是主外鍵約束關聯時,我們可以利用父子關系對這兩個表進行分區。只要對父表做形式上的分區,然后子表就可以繼承父表的分 區鍵。 如果沒有11g的引用分區,你想在兩個表上都建立對應的分區,那么需要使兩表分別有相同名稱的鍵值列。引用分區的好處是避免了在子表 上也建立父表同樣的一個分區鍵列,父表上的任何分區維護操作都將自動的級聯到子表上。例: SQL> CREATE TABLE purchase_orders?(po_id NUMBER(4),po_date TIMESTAMP,?supplier_id NUMBER(6),?po_total NUMBER(8,2),CONSTRAINT order_pk PRIMARY KEY(po_id))? PARTITION BY RANGE(po_date)(PARTITION Q1 VALUES LESS THAN (TO_DATE('2007-04-01','yyyy-mm-dd')),?PARTITION Q2 VALUES LESS THAN (TO_DATE('2007-06-01','yyyy-mm-dd')),?PARTITION Q3 VALUES LESS THAN (TO_DATE('2007-10-01','yyyy-mm-dd')),?PARTITION Q4 VALUES LESS THAN (TO_DATE('2008-01-01','yyyy-mm-dd')));//父表做了一個Range分區(可對引用分區使用除間隔分區外的所有分區策略)SQL> CREATE TABLE purchase_order_items?(po_id NUMBER(4) NOT NULL,?product_id NUMBER(6) NOT NULL,?unit_price NUMBER(8,2),?quantity NUMBER(8),?CONSTRAINT po_items_fk FOREIGN KEY (po_id) REFERENCES purchase_orders(po_id))?PARTITION BY REFERENCE(po_items_fk);//主表使用po_date鍵值列做范圍分區,子表中沒有po_date列,也想做相應的分區,那么使用引用分區吧。 //子表最后一句PARTITION BY REFERENCE()子句給出了引用分區約束名,使用的是子表的外鍵約束名。 //子表的po_id列必須是NOT NULL。這與通常的外鍵可以是NULL是有區別的。SQL> select TABLE_NAME,PARTITION_NAME,HIGH_VALUE from user_tab_partitions;TABLE_NAME ? ? ? ? ? ? ? ? ? ? PARTITION_NAME ? ? ? ? ? ? ? ? HIGH_VALUE ------------------------------ ------------------------------ -------------------------------------------------------------------------------- PURCHASE_ORDERS ? ? ? ? ? ? ? ? ? ? Q1 ? ? ? ? ? ? ? ? ? ? ? ? ? ? TIMESTAMP' 2007-04-01 00:00:00' PURCHASE_ORDERS ? ? ? ? ? ? ? ? ? ? Q2 ? ? ? ? ? ? ? ? ? ? ? ? ? ? TIMESTAMP' 2007-06-01 00:00:00' PURCHASE_ORDERS ? ? ? ? ? ? ? ? ? ? Q3 ? ? ? ? ? ? ? ? ? ? ? ? ? ? TIMESTAMP' 2007-10-01 00:00:00' PURCHASE_ORDERS ? ? ? ? ? ? ? ? ? ? Q4 ? ? ? ? ? ? ? ? ? ? ? ? ? ? TIMESTAMP' 2008-01-01 00:00:00' PURCHASE_ORDER_ITEMS ? ? ? ? ? Q1 ? ? ? ? ? ? ? ? ? ? ? ? ? ?? PURCHASE_ORDER_ITEMS ? ? ? ? ? Q2 ? ? ? ? ? ? ? ? ? ? ? ? ? ?? PURCHASE_ORDER_ITEMS ? ? ? ? ? Q3 ? ? ? ? ? ? ? ? ? ? ? ? ? ?? PURCHASE_ORDER_ITEMS ? ? ? ? ? Q4 ? ? ? ? ? ? ? ? ? ? ? ? ? ??8 rows selected//子表purchase_order_items也自動產生了四個分區,Q1,Q2,Q3,Q4.高值為空,意味者此處邊界由父表派生。SQL> select TABLE_NAME,PARTITIONING_TYPE,REF_PTN_CONSTRAINT_NAME from user_part_tables;TABLE_NAME ? ? ? ? ? ? ? ? ? ? PARTITIONING_TYPEREF_PTN_CONSTRAINT_NAME ------------------------------ ----------------------------------------------- PURCHASE_ORDERS ? ? ? ? ? ? ? ? ? ? RANGE ? ? ? ? ? ?? PURCHASE_ORDER_ITEMS ? ? ? ? ? REFERENCE ? ? ? ? PO_ITEMS_FK// PO_ITEMS_FK列是外鍵約束名稱12.2.4 Virtual Column-Based Partitioning(虛擬列分區)先了解一下什么叫虛擬列。虛擬列是11g的新特性:1> 只能在堆組織表(普通表)上創建虛擬列 2> 虛擬列的值并不是真實存在的,只有用到時,才根據表達式計算出虛擬列的值,磁盤上并不存放。 3> 可在虛擬列上建立索引。 4> 如果在已經創建的表中增加虛擬列時,若沒有指定虛擬列的字段類型,ORACLE會根據 generated always as 后面的表達式計算的結果自動設置該字段的類型。 5> 虛擬列的值由ORACLE根據表達式自動計算得出,不可以做UPDATE和INSERT操作,可以對虛擬列做DELETE 操作。 6> 表達式中的所有列必須在同一張表。 7> 表達式不能使用其他虛擬列。8> 可把虛擬列當做分區關鍵字建立虛擬列分區表,這正是我們要講的虛擬列分區。create table emp1(empno number(4) primary key,ename char(10) not null,salary number(5) not null,bonus number(5) ?not null,total_sal AS (salary+bonus)) partition by range (total_sal)(partition p1 values less than (5000),partition p2 values less than (maxvalue))enable row movement;insert into emp1(empno,ename,salary,bonus) values(7788,'SCOTT',3000,1000); insert into emp1(empno,ename,salary,bonus) values(7902,'FORD',4000,1500); insert into emp1(empno,ename,salary,bonus) values(7839,'KING',5000,3500); commit;SQL> select * from user_tab_partitions; SQL> select * from user_part_key_columns;SQL> select * from emp1 partition (p1);EMPNO ?ENAME ? ? ? ? ?SALARY ? ? ?BONUS ?TOTAL_SAL ---------- ? ?---------- ? ? ? ? ---------- ? ? ?---------- ? ?----------7788 ? ? ?SCOTT ? ? ? ? ? ?3000 ? ? ? ? 1000 ? ? ? 4000SQL> select * from emp1 partition (p2);EMPNO ? ENAME ? ? ? ? ?SALARY ? ? ?BONUS ?TOTAL_SAL ---------- ? ? ---------- ? ? ?---------- ? ? ? ?---------- ? ----------7902 ? ? ?FORD ? ? ? ? ? ? 4000 ? ? ? ? ?1500 ? ? ? 55007839 ? ? ?KING ? ? ? ? ? ? ?5000 ? ? ? ? ?3500 ? ? ? 8500SQL> update emp1 set bonus=500 where empno=7902;在建表時就使能了行移動(enable row movement),當更新分區鍵值時就不會報錯(ORA-14402: 更新分區關鍵字列將導致分區 的更改)12.2.5 More Composite Partitioning 在10g中,我們知道復合分區只支持Range-List和Range-Hash,而在在11g中復合分區的類型大大增加,現在Range,List,Interval都可 以作為Top level分區,而Second level則可以是Range,List,Hash,也就是在11g中可以有3*3=9種復合分區,滿足更多的業務需求。12.3 Oracle11g 的聯機重定義功能聯機條件下把普通的堆表轉換成分區表(11g新特性)例:聯機創建分區表:將emp1表聯機重定義,要求完成兩個任務,使其按照 sal分區(以2500為界),并去掉comm列。這個過程需要建 立一個臨時分區表emp1_temp完成復制轉換。sys下執行create table scott.emp1 as select * from scott.emp;alter table scott.emp1 add constraint pk_emp1 primary key(empno);1) 檢查原始表是否具有在線重定義資格,(要求表自包含及之前沒有建立實體化視圖及日志) SQL> BEGINDBMS_REDEFINITION.CAN_REDEF_TABLE('scott','emp1'); 該包要求表要有primary key END; /2) 創建一個臨時分區表:emp1_temp, 含有7列(刪去comm列),然后range分區,兩個區以sal=2500為界。 SQL> CREATE TABLE scott.emp1_temp(empno ? ? ? ?number(4) not null,ename ? ? ? ?varchar2(10),job ? ? ? ? ?varchar2(9),mgr ? ? ? ? ?number(4),hiredate ? ? date,sal ? ? ? ? ?number(7,2),deptno ? ? ? number(2)) PARTITION BY RANGE(sal)(PARTITION sal_low VALUES LESS THAN(2500),PARTITION sal_high VALUES LESS THAN (maxvalue));3)啟動聯機重定義處理過程 SQL> BEGINdbms_redefinition.start_redef_table('scott','emp1','emp1_temp','empno empno,ename ename,job job,mgr mgr,hiredate hiredate,sal sal,deptno deptno'); END; /SQL> select count(*) from scott.emp1_temp;COUNT(*) ----------14SQL> select * from scott.emp1_temp partition(sal_low);EMPNO ENAME ? ? ?JOB ? ? ? ? ? ? ?MGR ?HIREDATE ? ? ? ? ? ? ? ? ? ? ? ?SAL ? ? DEPTNO ---------- ---------- --------- ---------- ------ ------------- ? ? ? ? ? ? ? ? ? ? ?---------- ? ? ?----------7369 SMITH ? ? ?CLERK ? ? ? ? ? ? ? ?7902 1980-12-17 00:00:00 ? ? ? ?800 ? ? ? ? 207499 ALLEN ? ? ?SALESMAN ? ? ? ?7698 1981-02-20 00:00:00 ? ? ? 1600 ? ? ? ?307521 WARD ? ? ?SALESMAN ? ? ? ?7698 1981-02-22 00:00:00 ? ? ? 1250 ? ? ? ?307654 MARTIN ? SALESMAN ? ? ? ?7698 1981-09-28 00:00:00 ? ? ? 1250 ? ? ? ?307782 CLARK ? ? ?MANAGER ? ? ? ? 7839 1981-06-09 00:00:00 ? ? ? 2450 ? ? ? ?107844 TURNER ? SALESMAN ? ? ? ?7698 1981-09-08 00:00:00 ? ? ? 1500 ? ? ? ?307876 ADAMS ? ?CLERK ? ? ? ? ? ? ? ?7788 1987-05-23 00:00:00 ? ? ? 1100 ? ? ? ?207900 JAMES ? ? ?CLERK ? ? ? ? ? ? ? ?7698 1981-12-03 00:00:00 ? ? ? ?950 ? ? ? ? 307934 MILLER ? ? CLERK ? ? ? ? ? ? ? ?7782 1982-01-23 00:00:00 ? ? ? 1300 ? ? ? ?10已選擇9行。SQL> select * from scott.emp1_temp partition(sal_high);EMPNO ENAME ? ? ?JOB ? ? ? ? ? ? ?MGR HIREDATE ? ? ? ? ? ? ? ? ? SAL ? ? DEPTNO ---------- ---------- --------- ---------- ------------------- ---------- ----------7566 JONES ? ? ?MANAGER ? ? ? ? 7839 1981-04-02 00:00:00 ? ? ? 2975 ? ? ? ? 207698 BLAKE ? ? ?MANAGER ? ? ? ? 7839 1981-05-01 00:00:00 ? ? ? 2850 ? ? ? ? 307788 SCOTT ? ? ?ANALYST ? ? ? ? ? 7566 1987-04-19 00:00:00 ? ? ? 3000 ? ? ? ? 207839 KING ? ? ? ?PRESIDENT ? ? ? ? ? ? ? ? 1981-11-17 00:00:00 ? ? ? 5000 ? ? ? ? 107902 FORD ? ? ? ANALYST ? ? ? ? ? 7566 1981-12-03 00:00:00 ? ? ? 3000 ? ? ? ? 20已選擇5行。這個時候emp1_temp的主鍵,索引,觸發器,授權等還沒有從原始表繼承過來,SQL> select constraint_name,constraint_type,table_name from user_constraints where table_name like 'EMP1%';CONSTRAINT_NAME ? ? ? ? ? ? ? ?CONSTRAINT_TYPE TABLE_NAME ------------------------------ --------------- ------------------------------ PK_EMP1 ? ? ? ? ? ? ? ? ? ? ? ? ?P ? ? ? ? ? ? ? ?EMP1 SYS_C009652 ? ? ? ? ? ? ? ? ? ?C ? ? ? ? ? ? ? EMP1_TEMP4) 復制依賴對象這一步的作用是:臨時分區表emp1_temp繼承原始表emp1的全部屬性:包括索引、約束和授權以及觸發器。SQL> DECLAREnum_errors PLS_INTEGER; BEGINDBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('scott','emp1','emp1_temp',DBMS_REDEFINITION.CONS_ORIG_PARAMS,TRUE,TRUE,TRUE,TRUE,num_errors); END; /SQL> select constraint_name,constraint_type,table_name from user_constraints where table_name like 'EMP1%';CONSTRAINT_NAME ? ? ? ? ? ? ? ?CONSTRAINT_TYPE TABLE_NAME ------------------------------ --------------- ------------------------------ PK_EMP1 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?P ? ? ? ? ? ? ? EMP1 SYS_C009652 ? ? ? ? ? ? ? ? ? ? ? C ? ? ? ? ? ? ?EMP1_TEMP TMP$$_PK_EMP10 ? ? ? ? ? ? ? ? ? ? P ? ? ? ? ? ? ? EMP1_TEMP這時候原始表emp1還沒有分區,SQL> select table_name,partition_name,high_value from user_tab_partitions;TABLE_NAME ? ? ? ? ? ? ? ? ? ? PARTITION_NAME ? ? ? ? ? ? ? ? HIGH_VALUE ------------------------------ ------------------------------ -------------------------------------------------------------- EMP1_TEMP ? ? ? ? ? ? ? ? ? ? ?SAL_HIGH ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?MAXVALUE EMP1_TEMP ? ? ? ? ? ? ? ? ? ? ?SAL_LOW ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 25005) 完成重定義過程。SQL> EXECUTE dbms_redefinition.finish_redef_table('scott','emp1','emp1_temp');SQL> select table_name,partition_name,high_value from user_tab_partitions;TABLE_NAME ? ? ? ? ? ? ? ? ? ? PARTITION_NAME ? ? ? ? ? ? ? ? HIGH_VALUE ------------------------------ ------------------------------ -------------------------------------------------------------- EMP1 ? ? ? ? ? ? ? ? ? ? ? ? ? SAL_HIGH ? ? ? ? ? ? ? ? ? ? ? MAXVALUE EMP1 ? ? ? ? ? ? ? ? ? ? ? ? ? SAL_LOW ? ? ? ? ? ? ? ? ? ? ? ?2500最后一步發生了什么事情:原始表emp1與臨時分區表emp1_temp互換名稱。12.4 索引組織表(IOT表:如果表經常以主鍵查詢,可以考慮建立索引組織表,加快表的訪問速度heap table 數據的存放是隨機的,獲取表中的數據時沒有明確的先后之分,在進行全表掃描的時候,并不是先插入的數據就先獲取。而IOT 表是一個完全B_tree索引結構的表,表結構按照索引(主鍵)有序組織,因此數據存放在插入以前就已經確定了其位置。由于IOT表是把普通表和索引合二而一了,這樣在進行查詢的時候就可以少訪問很多基表的blocks,但是插入和刪除的時,速度比普通的表要 慢一些。IOT表的葉子節點存儲了所有表列,因為已按主鍵排序,所以葉子節點上不需要再存儲rowid。表列較多時,設置溢出段將主鍵和其他字段數據分開來存儲以提高效率。溢出段是個可選項,如果選擇了溢出段,Oracle將為一個IOT表分配兩個段,一個是索引段,另一個是溢出段。溢出段有兩個子句pctthreshold和including說明: pctthreshold給出行大小和塊大小的百分比,當行數據在葉子節點占用大小超出這個閾值時,就以這個閾值將索引entry一分為二,包含 主鍵的一部分列值保留在索引段,而其他列值放入溢出段,即overflow到指定的存儲空間去。including 后面指定一個或多個列名(不含主鍵列),將這些列都放入索引段。即讓主鍵和一些常用的列在索引段,其余的列在溢出段。例: create table iot_timran(id int, name char(50), sal int,? constraint pk_timran primary key (id)) organization index pctthreshold 30 overflow tablespace users;使用select * from user_indexes 查看是否單獨有索引。SQL> select index_name,index_type,table_name from user_indexes;INDEX_NAME ? ? ? ? ? ? ? ? ? ? INDEX_TYPE ? ? ? ? ? ? ? ? ?TABLE_NAME ------------------------------ --------------------------- ------------------------------ PK_TIMRAN ? ? ? ? ? ? ? ? ? ? ?IOT - TOP ? ? ? ? ? ? ? ? ? ? IOT_TIMRAN PK_EMP ? ? ? ? ? ? ? ? ? ? ? ? ? ?NORMAL ? ? ? ? ? ? ? ? ? ? ?EMP PK_DEPT ? ? ? ? ? ? ? ? ? ? ? ? ? NORMAL ? ? ? ? ? ? ? ? ? ? ?DEPT通過user_segments視圖查看產生了兩個段。 SQL> select segment_name,segment_type,partition_name from user_segments;12.5 簇表(cluster table):兩個相互關聯的表的數據,物理上同時組織到一個簇塊中,當以后進行關聯讀取時,只要掃描一個數據塊就可以了,可以提高了IO效率。建立簇表的三個步驟:1)建立簇段cluster segment 2)基于簇,創建兩個相關表,這兩個表不建立單獨的段,每個表都關聯到cluster segment上。 3)為簇創建索引,生成索引段。create cluster cluster1(code_key number); create table student(sno1 number, sname varchar2(10)) cluster cluster1(sno1); create table address(sno2 number,zz varchar2(10)) cluster cluster1(sno2); create index index1 on cluster cluster1;?生成了cluster1段和index1段。查看簇的信息: select * from user_clusters; select * from user_clu_columns;刪除簇: drop table student; drop table address; drop cluster cluster1;12.6 臨時表 (Temporary Table)臨時表存放在當前登錄的臨時表空間下,它被每個session單獨使用,即隔離session間的數據,不同session看到的臨時表中的數據不一樣。每個session獨立支持rollback,基于事務的臨時段在事務結束后收回臨時段,基于會話的臨時段在會話結束后收回臨時段,總之沒有 DML鎖,沒有約束,可以建索引,視圖和觸發器,由于會產生少量UNDO信息所以會產生少量redo,節省資源,訪問數據快。兩種模式: 1)基于事務的臨時段:在事務提交時,就會自動刪除記錄,on commit delete rows。 2)基于會話的臨時段:當用戶退出session 時,才會自動刪除記錄, on commit preserve rows。例:scott: create global temporary table tmp_student(sno int,sname varchar2(10), sage int) on commit preserve rows;再用Scott開一個session? 兩邊插入記錄看看, 你可以在兩個session里插入同樣的記錄,井水不犯河水!要刪除臨時表,要所有session斷開連接,再做刪除。drop table tmp_table;12.7 只讀表 (11g新特性)在以前版本中,有只讀表空間但沒有只讀表。11g中增加了新特性----只讀表。SQL> alter table t read only; SQL> update t set id=2; update t set id=2* 第 1 行出現錯誤: ORA-12081: 不允許對表 "SCOTT"."T" 進行更新操作SQL> alter table t read write;注意點:只讀表可以drop,因為只需要在數據字典做標記,但是不能做DML,另外,truncate也不行,因為它們都在對只讀表做寫操作。12.8 壓縮表 (11g新特性)目的:去掉表列中數據存儲的重復值,提高空間利用率。對數據倉庫類的OLAP有意義(頻繁的DML操作的表可能不適用做壓縮表)可以壓縮:堆表(若指定表空間則壓縮該表空間下所有表),索引表,分區表,物化視圖。主要壓縮形式有兩種:Advanced 11gR2較之前版本在語法上有了變化1)Basic table compression 使用direct path loads(缺省),典型的是建立大批量的數據,如:create table as select...結構?Basic對應的語法是: CREATE TABLE ... COMPRESS BASIC; 替換 COMPRESS FOR DIRECT_LOAD OPERATIONS(舊)2)Advanced row compression 針對OLTP的任何SQL操作。CREATE TABLE ... COMPRESS FOR OLTP... 代替 CREATE TABLE ... COMPRESS FOR ALL OPERATIONS(舊)兩種壓縮的原理類似(PPT-II-481-482):當insert達到pctfree=閥值(basic對應的pctfree=0, Advanced對應的是pctfree=10),觸發 compress,之后可以繼續insert,再達到pctfree,再觸發compress....直至compress數據填滿block的pctfree以下部分。壓縮的是block中的冗余數據,這對節省db buffer有益。例如一個表有7個columns,5 rows,其中的一些column有重復的行值2190,13770,25-NOV-00,S,9999,23,161 2225,15720,28-NOV-00,S,9999,25,1450 34005,120760,29-NOV-00,P,9999,44,2376 9425,4750,29-NOV-00,I,9999,11,979 1675,46750,29-NOV-00,S,9999,19,1121壓縮這個表后,存儲形式成為如下,重復值用符號替代。2190,13770,25-NOV-00,S,%,23,161 2225,15720,28-NOV-00,S,%,25,1450 34005,120760,*,P,%,44,2376 9425,4750,*,I,%,11,979 1675,46750,*,S,%,19,1121那么自然要對這些符號做些說明,相當于有個符號表Symbol Value ColumnRows? * 29-NOV-00 3 958-960 % 9999 5 956-960 ---------------------OLTP和OLAP
?數據處理大致可以分成兩大類:聯機事務處理OLTP(on-line?transaction?processing)、聯機分析處理OLAP(On-Line?Analytical?Processing)。OLTP是傳統的關系型數據庫的主要應用,主要是基本的、日常的事務處理,例如銀行交易。OLAP是數據倉庫系統的主要應用,支持復雜的分析操作,側重決策支持,并且提供直觀易懂的查詢結果。OLTP?系統強調數據庫內存效率,強調內存各種指標的命令率,強調綁定變量,強調并發操作;OLAP?系統則強調數據分析,強調SQL執行市場,強調磁盤I/O,強調分區等。OLTP與OLAP之間的比較:什么是OLTPOLTP,也叫聯機事務處理(Online?Transaction?Processing),表示事務性非常高的系統,一般都是高可用的在線系統,以小的事務以及小的查詢為主,評估其系統的時候,一般看其每秒執行的Transaction以及Execute?SQL的數量。在這樣的系統中,單個數據庫每秒處理的Transaction往往超過幾百個,或者是幾千個,Select?語句的執行量每秒幾千甚至幾萬個。典型的OLTP系統有電子商務系統、銀行、證券等,如美國eBay的業務數據庫,就是很典型的OLTP數據庫。OLTP系統最容易出現瓶頸的地方就是CPU與磁盤子系統。(1)CPU出現瓶頸常表現在邏輯讀總量與計算性函數或者是過程上,邏輯讀總量等于單個語句的邏輯讀乘以執行次數,如果單個語句執行速度雖然很快,但是執行次數非常多,那么,也可能會導致很大的邏輯讀總量。設計的方法與優化的方法就是減少單個語句的邏輯讀,或者是減少它們的執行次數。另外,一些計算型的函數,如自定義函數、decode等的頻繁使用,也會消耗大量的CPU時間,造成系統的負載升高,正確的設計方法或者是優化方法,需要盡量避免計算過程,如保存計算結果到統計表就是一個好的方法。(2)磁盤子系統在OLTP環境中,它的承載能力一般取決于它的IOPS處理能力.?因為在OLTP環境中,磁盤物理讀一般都是db?file?sequential?read,也就是單塊讀,但是這個讀的次數非常頻繁。如果頻繁到磁盤子系統都不能承載其IOPS的時候,就會出現大的性能問題。OLTP比較常用的設計與優化方式為Cache技術與B-tree索引技術,Cache決定了很多語句不需要從磁盤子系統獲得數據,所以,Web?cache與Oracle?data?buffer對OLTP系統是很重要的。另外,在索引使用方面,語句越簡單越好,這樣執行計劃也穩定,而且一定要使用綁定變量,減少語句解析,盡量減少表關聯,盡量減少分布式事務,基本不使用分區技術、MV技術、并行技術及位圖索引。因為并發量很高,批量更新時要分批快速提交,以避免阻塞的發生。OLTP?系統是一個數據塊變化非常頻繁,SQL?語句提交非常頻繁的系統。?對于數據塊來說,應盡可能讓數據塊保存在內存當中,對于SQL來說,盡可能使用變量綁定技術來達到SQL?重用,減少物理I/O?和重復的SQL?解析,從而極大的改善數據庫的性能。?這里影響性能除了綁定變量,還有可能是熱快(hot?block)。?當一個塊被多個用戶同時讀取時,Oracle?為了維護數據的一致性,需要使用Latch來串行化用戶的操作。當一個用戶獲得了latch后,其他用戶就只能等待,獲取這個數據塊的用戶越多,等待就越明顯。?這就是熱快的問題。?這種熱快可能是數據塊,也可能是回滾端塊。?對于數據塊來講,通常是數據庫的數據分布不均勻導致,如果是索引的數據塊,可以考慮創建反向所以來達到重新分布數據的目的,對于回滾段數據塊,可以適當多增加幾個回滾段來避免這種爭用。什么是OLAPOLAP,也叫聯機分析處理(Online?Analytical?Processing)系統,有的時候也叫DSS決策支持系統,就是我們說的數據倉庫。在這樣的系統中,語句的執行量不是考核標準,因為一條語句的執行時間可能會非常長,讀取的數據也非常多。所以,在這樣的系統中,考核的標準往往是磁盤子系統的吞吐量(帶寬),如能達到多少MB/s的流量。磁盤子系統的吞吐量則往往取決于磁盤的個數,這個時候,Cache基本是沒有效果的,數據庫的讀寫類型基本上是db?file?scattered?read與direct?path?read/write。應盡量采用個數比較多的磁盤以及比較大的帶寬,如4Gb的光纖接口。在OLAP系統中,常使用分區技術、并行技術。分區技術在OLAP系統中的重要性主要體現在數據庫管理上,比如數據庫加載,可以通過分區交換的方式實現,備份可以通過備份分區表空間實現,刪除數據可以通過分區進行刪除,至于分區在性能上的影響,它可以使得一些大表的掃描變得很快(只掃描單個分區)。另外,如果分區結合并行的話,也可以使得整個表的掃描會變得很快。總之,分區主要的功能是管理上的方便性,它并不能絕對保證查詢性能的提高,有時候分區會帶來性能上的提高,有時候會降低。并行技術除了與分區技術結合外,在Oracle?10g中,與RAC結合實現多節點的同時掃描,效果也非常不錯,可把一個任務,如select的全表掃描,平均地分派到多個RAC的節點上去。在OLAP系統中,不需要使用綁定(BIND)變量,因為整個系統的執行量很小,分析時間對于執行時間來說,可以忽略,而且可避免出現錯誤的執行計劃。但是OLAP中可以大量使用位圖索引,物化視圖,對于大的事務,盡量尋求速度上的優化,沒有必要像OLTP要求快速提交,甚至要刻意減慢執行的速度。綁定變量真正的用途是在OLTP系統中,這個系統通常有這樣的特點,用戶并發數很大,用戶的請求十分密集,并且這些請求的SQL?大多數是可以重復使用的。對于OLAP系統來說,絕大多數時候數據庫上運行著的是報表作業,執行基本上是聚合類的SQL?操作,比如group?by,這時候,把優化器模式設置為all_rows是恰當的。?而對于一些分頁操作比較多的網站類數據庫,設置為first_rows會更好一些。?但有時候對于OLAP?系統,我們又有分頁的情況下,我們可以考慮在每條SQL?中用hint。?如:Select?/*+first_rows(10)?*/?a.*?from?table?a;分開設計與優化在設計上要特別注意,如在高可用的OLTP環境中,不要盲目地把OLAP的技術拿過來用。如分區技術,假設不是大范圍地使用分區關鍵字,而采用其它的字段作為where條件,那么,如果是本地索引,將不得不掃描多個索引,而性能變得更為低下。如果是全局索引,又失去分區的意義。并行技術也是如此,一般在完成大型任務時才使用,如在實際生活中,翻譯一本書,可以先安排多個人,每個人翻譯不同的章節,這樣可以提高翻譯速度。如果只是翻譯一頁書,也去分配不同的人翻譯不同的行,再組合起來,就沒必要了,因為在分配工作的時間里,一個人或許早就翻譯完了。位圖索引也是一樣,如果用在OLTP環境中,很容易造成阻塞與死鎖。但是,在OLAP環境中,可能會因為其特有的特性,提高OLAP的查詢速度。MV也是基本一樣,包括觸發器等,在DML頻繁的OLTP系統上,很容易成為瓶頸,甚至是Library?Cache等待,而在OLAP環境上,則可能會因為使用恰當而提高查詢速度。對于OLAP系統,在內存上可優化的余地很小,增加CPU?處理速度和磁盤I/O?速度是最直接的提高數據庫性能的方法,當然這也意味著系統成本的增加。比如我們要對幾億條或者幾十億條數據進行聚合處理,這種海量的數據,全部放在內存中操作是很難的,同時也沒有必要,因為這些數據快很少重用,緩存起來也沒有實際意義,而且還會造成物理I/O相當大。?所以這種系統的瓶頸往往是磁盤I/O上面的。對于OLAP系統,SQL?的優化非常重要,因為它的數據量很大,做全表掃描和索引對性能上來說差異是非常大的。 --------------------- 概述 Oracle-OLAP和OLTP解讀Oracle-index索引解讀Oracle-分區表解讀Oracle-鎖解讀Oracle-等待事件解讀Oracle-procedure/cursor解讀通常來說,我們把業務分為來兩類,在線事務處理系統(OLTP)和在線分析系統(OLAP)或者DSS(決策支持系統),這兩類系統在數據庫的設計上是如此的不同,甚至有些地方的設計是像相悖的。比如: OLTP 系統強調數據庫的內存效率,強調內存各種指標的命中率,強調綁定變量,強調并發操作OLAP 系統則強調數據分析,強調SQL 執行時長,強調磁盤I/O,強調分區等。OLTP(on-line transaction processing)數據庫 通常來講,OLTP(在線事務處理系統)的用戶并發數都很多,但他們只對數據庫做很小的操作,數據庫側重于對用戶操作的快速響應,這是對數據庫最重要的性能要求。對于一個OLTP 系統來說,數據庫內存設計顯得很重要,如果數據都可以在內存中處理,那么數據庫的性能無疑會提高很多。內存的設計通常是通過調整Oracle 和內存相關的初始化參數來實現的,比較重要的幾個是內存相關的參數,包括SGA 的大小(Data Buffer,Shared Pool),PGA 大小(排序區,Hash 區等)等,這些參數在一個OLTP 系統里顯得至關重要,OLTP 系統是一個數據塊變化非常頻繁,SQL 語句提交非常頻繁的一個系統。對于數據塊來說,應盡可能讓數據塊保存在內存當中,對于SQL 來說,盡可能使用變量綁定技術來達到SQL 的重用,減少物理I/O 和重復的SQL 解析,能極大的改善數據庫的性能。除了內存,沒有綁定變量的SQL 會對OLTP 數據庫造成極大的性能影響之外,還有一些因素也會導致數據庫的性能下降,比如熱塊(hot block)的問題,當一個塊被多個用戶同時讀取的時候,Oracle 為了維護數據的一致性,需要使用Latch 來串行化用戶的操作,當一個用戶獲得了這個Latch,其他的用戶就只能被迫的等待,獲取這個數據塊的用戶越多,等待就越明顯,就造成了這種熱塊問題。這種熱塊可能是數據塊,也可能是回滾段塊。對于數據塊來講,通常是數據塊上的數據分布不均勻導致,如果是索引的數據塊,可以考慮創建反向索引來達到重新分布數據的目的,對于回滾段數據塊,可以適當多增加幾個回滾段來避免這種爭用。OLAP(On-Line Analytical Processing)數據庫 OLAP 數據庫在內存上可優化的余地很小,甚至覺得增加CPU 處理速度和磁盤I/O 速度是最直接的提高數據庫性能的方式,但這將意味著著系統成本的增加。實際上,用戶對OLAP 系統性能的期望遠遠沒有對OLTP 性能的期望那么高。對于OLAP 系統,SQL 的優化顯得非常重要試想,如果一張表中只有幾千數據,無論執行全表掃描或是使用索引,對我們來說差異都很小,幾乎感覺不出來,但是當數據量提升到幾億或者幾十億或者更多的時候,全表掃描,索引可能導致極大的性能差異,因此SQL得優化顯得重要起來。分區技術在OLAP 數據庫中很重要這種重要主要是體現在數據管理上,比如數據加載,可以通過分區交換的方式實現,備份可以通過備份分區表空間,刪除數據可以通過分區進行刪除。聯機事務處理(OLTP)和聯機分析處理(OLAP)的不同 聯機事務處理(OLTP)和聯機分析處理(OLAP)的不同,主要通過以下五點區分開來。1.用戶和系統的面向性: OLTP是面向顧客的,用于事務和查詢處理 OLAP是面向市場的,用于數據分析2.數據內容: OLTP系統管理當前數據. OLAP系統管理大量歷史數據,提供匯總和聚集機制.3.數據庫設計: OLTP采用實體-聯系ER模型和面向應用的數據庫設計. OLAP采用星型或雪花模型和面向主題的數據庫設計.4.視圖: OLTP主要關注一個企業或部門內部的當前數據,不涉及歷史數據或不同組織的數據 OLAP則相反.5.訪問模式: OLTP系統的訪問主要由短的原子事務組成.這種系統需要并行和恢復機制. OLAP系統的訪問大部分是只讀操作OLTP是傳統的關系型數據庫的主要應用,主要是基本的、日常的事務處理,例如銀行交易。OLAP是數據倉庫系統的主要應用,支持復雜的分析操作,側重決策支持,并且提供直觀易懂的查詢結果。 ---------------------?
總結
以上是生活随笔為你收集整理的ORACLE 表类型 OLTP和OLAP的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle 同义词、DBLINK、表空
- 下一篇: 数据切分 垂直切分、垂直拆分与水平拆分的