900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > ORACLE 表类型 OLTP和OLAP

ORACLE 表类型 OLTP和OLAP

时间:2021-03-23 05:15:41

相关推荐

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 21000AAASvVAAEAAAAGdAAB 11200一般来说范围分区的分区字段使用数字类型或日期类型,使用字符类型的语法是可以的,实际工作中使用较少。这或许跟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) globalpartition 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('-02-01','yyyy-mm-dd') ));SQL> insert into interval_sales values(1, to_date('-01-21','yyyy-mm-dd') );SQL> insert into interval_sales values(2, to_date('-02-01','yyyy-mm-dd') );--越过p1分区上线,将自动建立一个分区SQL> select partition_name from user_tab_partitions;PARTITION_NAME------------------------------P1SYS_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;C1C2---------- ----------1345注意:如果要删除以上表空间,必须先删除其上的分区表,否则会报错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('-04-01','yyyy-mm-dd')),PARTITION Q2 VALUES LESS THAN (TO_DATE('-06-01','yyyy-mm-dd')),PARTITION Q3 VALUES LESS THAN (TO_DATE('-10-01','yyyy-mm-dd')),PARTITION Q4 VALUES LESS THAN (TO_DATE('-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 Q1TIMESTAMP' -04-01 00:00:00'PURCHASE_ORDERS Q2TIMESTAMP' -06-01 00:00:00'PURCHASE_ORDERS Q3TIMESTAMP' -10-01 00:00:00'PURCHASE_ORDERS Q4TIMESTAMP' -01-01 00:00:00'PURCHASE_ORDER_ITEMSQ1 PURCHASE_ORDER_ITEMSQ2 PURCHASE_ORDER_ITEMSQ3 PURCHASE_ORDER_ITEMSQ4 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 RANGEPURCHASE_ORDER_ITEMSREFERENCEPO_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 ENAMESALARY BONUS TOTAL_SAL---------- -------------------- ---------- ----------7788 SCOTT30001000 4000SQL> select * from emp1 partition (p2);EMPNO ENAMESALARY BONUS TOTAL_SAL---------- ---------- ---------- ---------- ----------7902 FORD 40001500 55007839 KING 50003500 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 keyEND;/2) 创建一个临时分区表:emp1_temp, 含有7列(删去comm列),然后range分区,两个区以sal=2500为界。SQL>CREATE TABLE scott.emp1_temp(empno number(4) not null,ename varchar2(10),jobvarchar2(9),mgrnumber(4),hiredate date,salnumber(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 800207499 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 MANAGER7839 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 950307934 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 HIREDATESAL DEPTNO---------- ---------- --------- ---------- ------------------- ---------- ----------7566 JONES MANAGER7839 1981-04-02 00:00:00 2975207698 BLAKE MANAGER7839 1981-05-01 00:00:00 2850307788 SCOTT ANALYST7566 1987-04-19 00:00:00 3000207839 KING PRESIDENT 1981-11-17 00:00:00 5000107902 FORD ANALYST7566 1981-12-03 00:00:00 300020已选择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 EMP1SYS_C009652C 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 EMP1SYS_C009652 C EMP1_TEMPTMP$$_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_HIGHMAXVALUEEMP1_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 MAXVALUEEMP1 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_TIMRANPK_EMP NORMAL EMPPK_DEPT NORMAL DEPT通过user_segments视图查看产生了两个段。SQL> select segment_name,segment_type,partition_name from user_segments;12.5 簇表(cluster table):两个相互关联的表的数据,物理上同时组织到一个簇块中,当以后进行关联读取时,只要扫描一个数据块就可以了,可以提高了IO效率。建立簇表的三个步骤:1)建立簇段cluster segment2)基于簇,创建两个相关表,这两个表不建立单独的段,每个表都关联到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,1612225,15720,28-NOV-00,S,9999,25,145034005,120760,29-NOV-00,P,9999,44,23769425,4750,29-NOV-00,I,9999,11,9791675,46750,29-NOV-00,S,9999,19,1121压缩这个表后,存储形式成为如下,重复值用符号替代。2190,13770,25-NOV-00,S,%,23,1612225,15720,28-NOV-00,S,%,25,145034005,120760,*,P,%,44,23769425,4750,*,I,%,11,9791675,46750,*,S,%,19,1121那么自然要对这些符号做些说明,相当于有个符号表Symbol Value ColumnRows* 29-NOV-00 3 958-960% 9999 5 956-960---------------------

OLTP和OLAP

数据处理大致可以分成两大类:联机事务处理OLTP(on-linetransactionprocessing)、联机分析处理OLAP(On-LineAnalyticalProcessing)。OLTP是传统的关系型数据库的主要应用,主要是基本的、日常的事务处理,例如银行交易。OLAP是数据仓库系统的主要应用,支持复杂的分析操作,侧重决策支持,并且提供直观易懂的查询结果。OLTP系统强调数据库内存效率,强调内存各种指标的命令率,强调绑定变量,强调并发操作;OLAP系统则强调数据分析,强调SQL执行市场,强调磁盘I/O,强调分区等。OLTP与OLAP之间的比较:什么是OLTPOLTP,也叫联机事务处理(OnlineTransactionProcessing),表示事务性非常高的系统,一般都是高可用的在线系统,以小的事务以及小的查询为主,评估其系统的时候,一般看其每秒执行的Transaction以及ExecuteSQL的数量。在这样的系统中,单个数据库每秒处理的Transaction往往超过几百个,或者是几千个,Select语句的执行量每秒几千甚至几万个。典型的OLTP系统有电子商务系统、银行、证券等,如美国eBay的业务数据库,就是很典型的OLTP数据库。OLTP系统最容易出现瓶颈的地方就是CPU与磁盘子系统。(1)CPU出现瓶颈常表现在逻辑读总量与计算性函数或者是过程上,逻辑读总量等于单个语句的逻辑读乘以执行次数,如果单个语句执行速度虽然很快,但是执行次数非常多,那么,也可能会导致很大的逻辑读总量。设计的方法与优化的方法就是减少单个语句的逻辑读,或者是减少它们的执行次数。另外,一些计算型的函数,如自定义函数、decode等的频繁使用,也会消耗大量的CPU时间,造成系统的负载升高,正确的设计方法或者是优化方法,需要尽量避免计算过程,如保存计算结果到统计表就是一个好的方法。(2)磁盘子系统在OLTP环境中,它的承载能力一般取决于它的IOPS处理能力.因为在OLTP环境中,磁盘物理读一般都是dbfilesequentialread,也就是单块读,但是这个读的次数非常频繁。如果频繁到磁盘子系统都不能承载其IOPS的时候,就会出现大的性能问题。OLTP比较常用的设计与优化方式为Cache技术与B-tree索引技术,Cache决定了很多语句不需要从磁盘子系统获得数据,所以,Webcache与Oracledatabuffer对OLTP系统是很重要的。另外,在索引使用方面,语句越简单越好,这样执行计划也稳定,而且一定要使用绑定变量,减少语句解析,尽量减少表关联,尽量减少分布式事务,基本不使用分区技术、MV技术、并行技术及位图索引。因为并发量很高,批量更新时要分批快速提交,以避免阻塞的发生。OLTP系统是一个数据块变化非常频繁,SQL语句提交非常频繁的系统。对于数据块来说,应尽可能让数据块保存在内存当中,对于SQL来说,尽可能使用变量绑定技术来达到SQL重用,减少物理I/O和重复的SQL解析,从而极大的改善数据库的性能。这里影响性能除了绑定变量,还有可能是热快(hotblock)。当一个块被多个用户同时读取时,Oracle为了维护数据的一致性,需要使用Latch来串行化用户的操作。当一个用户获得了latch后,其他用户就只能等待,获取这个数据块的用户越多,等待就越明显。这就是热快的问题。这种热快可能是数据块,也可能是回滚端块。对于数据块来讲,通常是数据库的数据分布不均匀导致,如果是索引的数据块,可以考虑创建反向所以来达到重新分布数据的目的,对于回滚段数据块,可以适当多增加几个回滚段来避免这种争用。什么是OLAPOLAP,也叫联机分析处理(OnlineAnalyticalProcessing)系统,有的时候也叫DSS决策支持系统,就是我们说的数据仓库。在这样的系统中,语句的执行量不是考核标准,因为一条语句的执行时间可能会非常长,读取的数据也非常多。所以,在这样的系统中,考核的标准往往是磁盘子系统的吞吐量(带宽),如能达到多少MB/s的流量。磁盘子系统的吞吐量则往往取决于磁盘的个数,这个时候,Cache基本是没有效果的,数据库的读写类型基本上是dbfilescatteredread与directpathread/write。应尽量采用个数比较多的磁盘以及比较大的带宽,如4Gb的光纤接口。在OLAP系统中,常使用分区技术、并行技术。分区技术在OLAP系统中的重要性主要体现在数据库管理上,比如数据库加载,可以通过分区交换的方式实现,备份可以通过备份分区表空间实现,删除数据可以通过分区进行删除,至于分区在性能上的影响,它可以使得一些大表的扫描变得很快(只扫描单个分区)。另外,如果分区结合并行的话,也可以使得整个表的扫描会变得很快。总之,分区主要的功能是管理上的方便性,它并不能绝对保证查询性能的提高,有时候分区会带来性能上的提高,有时候会降低。并行技术除了与分区技术结合外,在Oracle10g中,与RAC结合实现多节点的同时扫描,效果也非常不错,可把一个任务,如select的全表扫描,平均地分派到多个RAC的节点上去。在OLAP系统中,不需要使用绑定(BIND)变量,因为整个系统的执行量很小,分析时间对于执行时间来说,可以忽略,而且可避免出现错误的执行计划。但是OLAP中可以大量使用位图索引,物化视图,对于大的事务,尽量寻求速度上的优化,没有必要像OLTP要求快速提交,甚至要刻意减慢执行的速度。绑定变量真正的用途是在OLTP系统中,这个系统通常有这样的特点,用户并发数很大,用户的请求十分密集,并且这些请求的SQL大多数是可以重复使用的。对于OLAP系统来说,绝大多数时候数据库上运行着的是报表作业,执行基本上是聚合类的SQL操作,比如groupby,这时候,把优化器模式设置为all_rows是恰当的。而对于一些分页操作比较多的网站类数据库,设置为first_rows会更好一些。但有时候对于OLAP系统,我们又有分页的情况下,我们可以考虑在每条SQL中用hint。如:Select/*+first_rows(10)*/a.*fromtablea;分开设计与优化在设计上要特别注意,如在高可用的OLTP环境中,不要盲目地把OLAP的技术拿过来用。如分区技术,假设不是大范围地使用分区关键字,而采用其它的字段作为where条件,那么,如果是本地索引,将不得不扫描多个索引,而性能变得更为低下。如果是全局索引,又失去分区的意义。并行技术也是如此,一般在完成大型任务时才使用,如在实际生活中,翻译一本书,可以先安排多个人,每个人翻译不同的章节,这样可以提高翻译速度。如果只是翻译一页书,也去分配不同的人翻译不同的行,再组合起来,就没必要了,因为在分配工作的时间里,一个人或许早就翻译完了。位图索引也是一样,如果用在OLTP环境中,很容易造成阻塞与死锁。但是,在OLAP环境中,可能会因为其特有的特性,提高OLAP的查询速度。MV也是基本一样,包括触发器等,在DML频繁的OLTP系统上,很容易成为瓶颈,甚至是LibraryCache等待,而在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是数据仓库系统的主要应用,支持复杂的分析操作,侧重决策支持,并且提供直观易懂的查询结果。---------------------

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。