《Oracle9i&10g编程艺术》读书笔记

总体印象,这本书本身就写得浅显易懂,例子也多,基本上性能比较都在书中列出,节约了读者时间,看完数据库,要结合一个实例来分析的话,是很好的选择。另外,翻译得也很从不错,没有很晦涩的地方,读下来,不需要参照电子版的英文版,翻译得如此,确实是值这个价,虽然这本书是我借图书馆的,而且因为太大,所以多拖了一个多星期才还,虽然还是很多部分看得不是很仔细….

 

第1章        开发成功的Oracle应用

信守的思想:

l          如果可能,尽量以用一条SQL完成工作

l          如果无法用一SQL完成,通过PL/SQL完成

l          如果PL/SQL无法完成,使用Java存储过程实现

l          如果Java办不到,那就用C外部过程中实现。如果速度要求高,或使用C的第三方API

l          C外部例程中无法实现,就该好好想想有没有必要做这个工作。

 

正确方法

l          Oracle中使用一个连接,而不是像SQL Server那样,每条执行的并发语句都打开数据库连接。

l          使用绑定变量,在Java中即PrepareStatement.

l          理解并发控制,防止更新丢失

 

数据库的独立性

标准的影响,SQL

防御式编程,sequence,利用触发器插入主键,插入时,为主键插入sequence.NEXTVAL

开放性,作者认为,不遗余力地争取数据库的独立性和完全的开放性是一个错误的决定,不管什么数据库,都应该充分利用,把它的每一个功能都挤出来。

 

第2章          体系结构概述

数据库和实例的区别

数据库:物理操作系统文件或磁盘集合。

实例:一组Oralce后台进程以及一个共享内存区。由同一个计算机运行的线程、进程所共享。但集群时,是多个实例同时装载并打开一个数据库。

重申:

实例是一组后台进程和共享内存

数据库是磁盘上存储的数据集合

实例一生只能装载并打开一个数据库

数据库可以用一个或者多个实例(使用RAC)装载并打开,Real Application Clusters 实时应用集群

 

连接Oracle

专用服务器

共享服务器,由调度器处理请求队列和响应队列

TCP/IP连接的基本原理。TNS代表Transparent Network Substrate[Oracle_Home]/network/admin下配置

TNS监听器,可以建立专用(fork/exec)或共享服务器(给调度器)

 

第3章          文件

看得不是很仔细

 

参数文件:v$parameter Table,遗留的inti.ora参数文件

数据文件

segment 占用存储空间的数据库对象,如回滚段,临时段,聚簇段,索引段

区段 extent 段本身由一个或多个区段组成。它是文件中一个逻辑上连续分配的空间。

block 区段由块组成。Oracle最小的空间分配单位。默认大小:2/4/8/16KB,如操作系统允许,可有32KB的块大小。只有创建数据库指定非标准块大小(非2次幂),才会有6种块大小。故,一般5种。

块结构

l          首部

l          表目录

l          行目录

l          空闲空间

l          数据

l          尾部

 

表空间 table space 包含段。段绝对不会跨越表空间边界。表空间本身可有一个或多个相关数据文件。而其中一个区段extent在一个数据文件中。但段可以来自多个不同数据文件的区段。

总结:从大到小,表空间、段、区段、块

 

重做日志文件

每个Oracle数据库都至少有两个在线重做日志文件组。每个日志组都包含一个或多个重做日志成员。

在填满日志文件1并切换到日志文件2时,Oracle会启动一个检查点。data block writer就会把日志文件组1保护的脏块写入磁盘。

 

第4章          Oracle内存结构

看得不是很仔细

 

PGA Process Global Area

分为: *_AREA_SIZE, 例如SORT, HASH等操作

PGA是进程专用内存区,专用或共享服务器需要的一组独立于会话的变量。

 

UGA USER GLOBAL AREA

共享服务器,在SGA中分配;专用服务器,在PGA中分配

 

SGA System Global Area

分为:共享池、Java池、大池、流池、空池

共享池:Oracle缓存一些“程序”数据的地方,在解析一个查询时,解析得到的表示就缓存在这里。因此,运行的PL/SQL代码就在共享池中缓存,下一次运行时,Oracle不会再次从磁盘中读取。代码在这里共享和缓存。

 

破坏共享区原因:

l          大量CPU时间解析查询,即没有绑定变量

l          大量资源来管理共享池中对象,从来不重用查询

 

大池:用于大块内存的分配,共享池不会处理这么大的内存块。

主要用于以下情况:

共享服务器连接:在SGA中分配UGA

语句的并行执行

备份:用于RMAN磁盘I/O缓冲区

 

Java池:

Oracle 8 后增加的,在数据库中运行Java。如果Java编写存储过程,Oracle会在处理代码时使用Java池的内存。

 

流池: 10g 开始增加,共享/复制工具。

 

第5章          Oracle进程

看得不是很仔细

Oracle中的进程,在某些操作系统中,如windowsOracle用线程实现,因此这里要把所说的“进程”理解为“线程”的同义词。而Unix下的Oracle是多进程实现,“进程”就很贴切。

 

连接与会话

连接connection就是客户进程与Oracle实例间的一条物理路径,如一个网络连接。会话是数据库的一个逻辑实体。客户进程在会话上执行SQL,多个独立会话可以与一个连接相关联。

专用服务器下,客户连接和服务器进程之间有一个一对一的映射。共享服务器中,客户应用会连接到Oracle TNS监听器上,并重定向或转交给一个调度器。客户应用会与一个调度其进程物理连接。

 

一般来说,Disconnect命令 = Destroy all sessions, 断开连接要用exit命令,connect命令=create session

 

第6章         

锁定问题

丢失更新

悲观锁定:pessimistic locking  select … for update (nowait).

乐观锁定:Oracle实现由三种方法:

l          使用一个特殊的列,此列由触发器或应用程序代码维护,可以告诉我们记录的“版本”

l          使用一个校验或散列值,这是由原来数据计算得出的

l          使用Oracle 10g 特性ORA_ROWSCN,默认情况下,ORA_ROWSCN序号以块为单位推进,定义table时,需要加上ROWDEPENDENCIES来表示行独立性。其为内置特性,由Oracle自动执行,不需要在表中增加额外的列,也不需要额外的更新/维护代码来更新这个值。

 

DML锁、DDL锁,原来写过文章,不再详述。《Oracle中的并发控制.doc

 

轻量级的串行化设备,用于协调对共享数据结构、对象和文件的多用户访问。

闩“自旋”

解析SQL语句时,会为共享池中的库缓存和相关结构得到并释放数百个或数千个闩。等待闩可能是一个代价很高的操作。自旋是指在循环中反复等待尝试得到闩,这样实现是因为上下文切换的开销很大。如果进程不能立即得到闩,会一直呆在CPU上,并立即再次尝试,而不是先休眠,放弃CPU。如果自旋,但之后还是得不到闩,此时进程才会休眠。

 

第7章          并发与多版本

Oracle中的并发控制.doc

写一致性

Oracle提供了读一致性,考虑:update t set x=2 where y = 5;

在该语句运行时,有人将整条语句已经读取得一行从y=5更新为y=6. 即这句通过一致性读时,y=5,但现在y的当前值为6.更新会如何?即写一致性问题,这是多版本的数据库所特有的问题。

 

Oracle处理修改语句会完成两类块获取,会执行:

一致读:发现要修改的行时,所完成的获取就是一致读。

当前读:得到块来完成更新所需要修改的行时,所完成的获取就是当前读。

例子

select * from t

update t t1 set x=x+1

update t t1 set x=x+1

 

select没有当前读,第一个update会比select3个当前读,它们是获得要更新的块,获得undo段块,获得undo块。第二个update只有1个当前读,只要获得要更新的块,因为这三句是同一个事务,不需再完成撤销工作。

 

重启动例子:

事务1                                                      事务2

update t set y=10 where y =5

                                                                 update t set x=x+1 where y=5

commit.

 

这就是当前读的作用,事务2中,原来y=5的记录可能不再是5,这种情况下,事务2会选择重启动更新。

 

 

重启动的影响:

注意:触发器也会导致重启动,例如用:old/:new来使用数据时,Oracle发现其中有值与原来不一致时,就会从启动;而如果不引用时,就不会重启动。

 

如果一个批量更新,100,000行更新后,发生重启动,需要回滚100,000行数据,很大影响性能.

解决方法:解除触发器的所有非事务性工作,使之在事后的作业中完成.

 

第8章          事务

语句/过程原子性和事务原子性

 

过程中只要不捕获异常,Oracle遇到过程中有异常,就会回滚过程.

 

事务的 IMMEDIATE 约束和 DEFERRABLE约束,即语句时检查还是提交时才检查.

 

不好的事务习惯

l          循环中提交.

l          使用自动提交. Java中的 JDBC默认是自动提交,应该默认为conn.setAutoCommit(false);

 

自治事务

如果一个正常的过程中commit, 它不仅会持久保留自己的工作,也会使该会话未完成的工作成为持久性的。不过如果在一个自治事务中完成提交,只会让这个过程本身的工作成为永久性的。

 

书中有一个使用自治事务,AUDIT审计的例子,如果用触发器实现此功能,能检查到update,而且发现非法时,会记录,而且让update失败,但触发器失败时,也会使自己回滚。故要使用自治事务。在触发器中有一个自治事务。

 

第9章          redo undo

看得不仔细

 

修改数据库中的数据时,会发生以下操作:

l          已经在SGA中生成了Undo块。

l          已经在SGA中生成了已修改的数据块

l          已经在SGA中生成了前两相对应的缓存redo

l          取决于前三项大小,以及工作花费的时间,前面的某个数据可能已经输出到磁盘

l          已经得到所需的全部锁

 

commit时,余下的工作是:

l          为事务生成一个SCN

l          LGWR将所余下的缓存重做日志写至磁盘,并且把SCN记录到在线重做日志中。真正的commit,如果出现这一步,即已经提交。事务条目会从V$TRANSACTION中“删除”,说明我们已经提交。

l          V$LOCK中记录着我们会话中持有的锁,这些锁都会被释放,而排队等待这些锁的,会被唤醒

l          如果事务修改的某些块还在缓冲区缓存中,则会以一种快速的模式访问并“清理”。

 

rollback时,会做的工作:

l          撤销已做的所有修改。从undo段读会数据,然后实际上逆向执行前面所作的操作,并将undo条标记为已用。

l          释放所有锁。唤醒相关工作。

 

日志竞争

常见原因:

redo放在一个慢速设备上

redo与其它频繁访问的文件放在同一个设备上

以缓冲方式装载日志设备

redo使用一种慢速技术,例如RAID5,其适合读,但写时性能很差。

 

第10章       数据库表

看得不仔细

术语: 段、段空间管理、高水位线、freelistsPCTFREEPCTUSEDLOGGINGNOLOGGINGINITRANSMAXTRANS

堆组织表

索引组织表

索引聚簇表

聚簇表的概念和聚簇索引、非聚簇索引概念不同。

聚簇索引是物理位置按照索引键的值顺序排列。

非聚处索引,只是一个键值对,与数据物理位置没有关系。

 

散列聚簇表

有序散列聚簇表

嵌套表

临时表

对象表

 

第11章       索引

B*数索引

索引键压缩

在建立索引时,执行压缩类型,压缩带来的大小变化不是免费的,会花更多的话时间处理这个索引结构中的数据,不光在修改期间花费时间,查询期间也花更多时间。

 

反向键索引

使用RESERVE关键字

例子dump(90101,16)c3,a,2,2dump(90102,16)c3,a,2,3

dump(reserve(90101),16)2,2,a,c3dump(reserve(90102),16)3,2,a,c3

 

可以看到这样做数据之间会“相距很远”,这样在RAC应用,集群应用中,访问同一个块的RAC实例个数就能减少。反向索引的缺点之一是:能用常规索引的地方不一定能用反向索引。例如where x > 5;

 

如果在x,y中用反向索引,Oracle会存储(RESERVE(X)||RESERVE(Y)),而不是(RESERVE(X||Y))。因此X=5的查询有效。

反向索引有助于缓解缓冲区忙等待问题,但是取决于其他的一些因素。通过消除缓冲区忙等待,将对事务吞吐量稍有影响,同时随着并发度增加,反向索引可扩展性会增加。

 

 

降序索引

8i开始引入,用以扩展B*树索引的功能。它允许在索引中以降序而不是升序存储。

例如

create index desc_t idx on(owner desc, object_type asc)

 

这样在查询相同顺序的时候,可以直接利用索引,比起一般的索引会少一步sort操作。

 

使用索引的两种方法:

索引用于访问表中的行:希望你访问表中很少的一部分行。

索引用于回答一个查询:包含了足够的信息回答整个查询。

 

书中给出例子,物理组织对查询结构的影响,相同数据,相同的索引,就是物理组织不一致,一个是共同放置(co-located)和无组织(disorganized),都采用索引查询,性能差异很大。

结果还表明,对于物理块较分散的情况,做一次全表搜索反而效率更高。优化器会自己选择最优方案。

 

聚簇因子

之前的问题,引出聚簇因子的概念,可以把聚簇因子看作是通过索引读取整个表时对表执行的逻辑I/O次数。越低说明越聚簇。上面的例子中,聚簇因子在user_indexes.clustering_factor查出,刚刚的例子聚簇相差近100倍!

以上的关键点是,索引并不一定总是合适的访问方法,优化器也许选择不使用索引,而且这种选择可能是正确的。

 

 

位图索引

位图索引对于相异基数(distinct cardinality)低的数据最为合适。位图索引在读密集的环境中能很好地工作,但是对于写密集的环境则极不适用。原因在于,一个位图索引条目指向多行,修改所索引条目时,大多数情况下,会锁定整个位图索引条目。

 

位图联结索引

create bitmap index emp_bm_idx

on emp(d.dname)

         from emp e, dept p

         where e.deptno = d.deptno

 

这样对于select count(*) from emp, dept where emp.deptno=dept.deptno and dept.dname=”SALES”

的查询,不需要真正的访问EMP表或DEPT表,答案来自索引本身。

 

基于函数的索引

必须是DETERMINISTIC的函数才可以用来建立索引,即给定相同输入时,输出都是相同的。

只对部分建立索引

create index processed_flag_idx on big_table(case temporary when ‘N’ then ‘N’ end)

 

实现有选择的唯一性,基本上同“只对部分建立索引”

 

重写case,使索引在某些查询时不可用。

使用DECODE而不是CASE,因DECOEDE不会被重写。

 

对于to_char(to_date(‘2005’ ‘YYYY’),’DD-MON-YYYY HH24:MI:SS’)方法,不同月份会得到不同结果,因此不算DETERMINISTIC,不能用于创建索引。

 

关于索引的常见问题和神话

视图能适用索引吗?

其实还是对基表建立索引

 

NULL能和索引协作吗?

只有所有条目都为NULL的条目才会被索引忽略。例子:

create table t (x int, y int)

create unique index t_idx on t(x,y)

 

insert into t values(NULL,NULL)

insert into t values(1,NULL)

insert into t values(NULL,1)

insert into t values(NULL,NULL)可以再执行,原因不认为是新的(NULL,NULL)与旧的相同。这是Oracle实现,也是SQL标准要求的。

不过对于聚簇操作,(NULL,NULL)(NULL,NULL)则认为是相同的。

select x, y, count(*) from t group x, y having count(*)>1

结果,因为其他都是1。重复执行insert into t values(NULL,NULL),只有NULL,NULL2

X                Y                COUNT(*)

                                     2

 

外键是否应该加索引?

因为表锁的关系,当外键上没还有索引,修改父表的主键或者删除记录时,会对子表加表锁,使得效率很低,故一般都要为外键加索引。

如果满足以下条件则可以不需要加:

未删除父表中的行。

不论是有意还是无意,总之未更新父表中的唯一/主键值。

不会从父表联结到子表,或者更一般地说,外键列不支持子表的一个重要的访问路径,而且你在谓词中没有使用这些外键列从子表中选择数据。即

select * from dept, emp where emp.deptno = dept.deptno and dept.dname=:X

emp为子表,dept为父表

 

为什么没有使用我的索引?

情况1

使用一个B*索引,而且谓词中没有使用索引的最前列。例如对T(x,y)建立索引,用select * from t where y=5,优化器不打算使用索引,优化器通常会选择对T做一次全表扫描。但并不排除使用索引。

如果查询是Select x, y from t where y=5,优化器会注意到,对索引本身做一次扫描更合适。

 

另一情况下CBO使用(x,y)上的索引,这就是索引跳跃式扫描。当且仅当索引最前列只有很少的几个值。

这样的索引是,先按x做一次索引,然后对相同x下的y再做一次索引。因为,第一列值少,导致第一列的树结点少,很快就可以到第二列的索引排序。

 

情况2

select count(*) from T ,避免导致错误结果,因为有全NULL的条目

 

情况3

select * from t where f(index_column) = value

索引是在index_column上,而不是F(index)

 

情况4

对一个字符列建立了索引,但这个列只有数值数据,例如select * from t where indexed_column = 5indexed_column是字符列。

因系统隐式调用to_number(indexed_column),因此情况类似于情况3

优化技巧:

在函数上建立索引

改变SQL查询方式

select * from t where trunc(data_col) = trunc(sysdate);

可以变为:

select * from t where data_col >= trunc(sysdate) and data_col< trunc(sysdate+1)

这样就可以用data_col的索引了。

 

情况5

如果此时使用索引,实际上反而更慢,例如之前的物理组织影响的例子。

 

情况6

有一段时间没有分析表,这些表起先很小,等查看时,已经增长得很大,现在索引才有意义,如果没有正确的统计信息,CBO无法做出正确的决定。

 

神话:索引中从不重用空间

 

神话:最有差别的元素应该在最前面

经过Oracle的优化,按照各个列的差别大小来排列这些猎在索引中的顺序并不会获得本质上的效率提升。书中例子证明了这点,在Oracle中应该根据应用查询的具体情况,决定索引的创建情况

例如:

系统中有大量如下查询:

select * from t where c1 = x where c2=y

select * from t where c2=y

这样的话,创建(c2,c1)索引更合适,以上两个查询都能用到这个索引。

 

第12章       数据类型

CHAR:定长字符串,会用空格填充达到其最大长度,最多2000字节,CHAR(10)NULL,10字节

NCHAR:包含UNICODE格式数据的定长字符串,最多2000字节,注意NCHAR(10)NULL,总10字符

VARCHAR2:变长字符串,不会填充,最多4000字节,数字表示字节

NVARCHAR2:变长字符串,不会填充,最多4000字节,类似CHARNCHAR的区别,数字表示字符

RAW:变长二进制数据结构,最多2000字节

NUMBER:最多达38位数字,长度在0-22字节之间,精度很高,远高于多数编程语言的FLOATDOUBLE

BINARY_FLOAT 10g 以后的新类型。32位单精度浮点数,至少6位精度

BINARY­_DOUBLE:新类型。64位双精度,至少13位精度

LONG:最多2GB的字符数据,只是向前兼容,应该用CLOB类型

LONG­_RAW,只是向前兼容,应该用BLOB类型

DATE:这是7字节的定宽日期/时间数据结构,精确到秒

TIMESTAMP7或者11字节的定宽日期/时间数据结构,与DATE不同,TIMESTAMP精确到小数秒,带小数的秒最多保留9

TIMESTAMP WITH TIME ZONE:类似前一种,13字节,存储额外的关于时区信息

TIMESTAMP WITH LOCAL TIME ZONE7或者11字节,对时区敏感。如你想使用US/Pacific时区,而数据库时区为US/Eastern,那获得的时间会被转换为Eastern,再像TIMESTAMP那样存储。

INTERVAL YEAR TO MONTH5字节定宽数据类型。这个类型将时段存储为年数和月数。可以使用这种时间间隔使一个DATETIMESTAMP类型增加或减少一段时间。

INTERVAL DAY TO SECOND11字节,一个时段,天/小时/分钟/秒数,最多9位小数秒。

BFILE:存储一个Oracle目录对象和一个文件名,并读取这个文件。实际上允许你以只读方式访问数据库服务器上可用的操作系统系统文件。

BLOB9i和以前的版本中,可存储最多4GB字节数据。 10g 后允许4*数据库块大小 GB,适合存储电子表格、字处理文档、图像文件等。

CLOB:包含要进行字符集转换的信息,适合纯文本信息

NCLOB:类似CLOB,存储用数据库国家字符集编码信息,这些信息需要进行字符集转换。

ROWID:实际上是数据库中一行的10字节地址。足以在磁盘上定位这一行,以及标示ROWID指向的对象(表等)

UROWID:通用的ROWID,用于表。UROWID是行主键值的一种表示,因此,取决于所指向的对象,UROWID的大小会有所变化。

 

以上不全,如INT/SMALLINT/FLOAT等,这些类型实际是所列基本类型的基础上实现的。XMLTYPE等复杂类型也没有列出。

 

字符和二进制串类型

字符串编码NLS_CHARACTERSET

 

二进制RAW

每个二进制字节都显示为两个十六进制字符。因此看上去似乎超过其指定的长度,记住,显示的是16进制

 

NUMBER

NUMBER(p,s)

精度,合法取值为 1 - 38

小数位,合法取值为 -84 - 127

对于超精度的情况,报错提示

对于超小数位的情况,用舍入法解决。

 

小数位的负数表示精确到小数点往前数多少位,例如,-2位精确到100,十位个位将被舍入。

 

书中介绍处理遗留的LONG类型,不详述

 

 

日期类型

trunc(data_col, ‘y’) = to_date(’01-Jan -2005’ ,’dd-mm-yyyy’)

代替 to_char(date_col,’yyyy’) = ‘2005’

可以有性能上的优势,两者大概相差10倍左右。原因是,to_char把日期转换为字符串,有更长的代码路径,而trunc则是修改日期格式的字节,相当于mask。因此,应该尽量用trunc 代替 to_char进行日期截断。

 

向日期增加和减少时间:

常用的三种方法

l          DATE 增加一 NUMBER,例如加1,就是增加1天,1/24就是1小时。

l          INTERVAL类型增加时间单位,两种粒度:年和月,或日/小时/分钟/秒。

l          使用内置的ADD_MONTH函数增加月

 

TOM的建议:

l          使用NUMTODSINTERVAL内置函数增加小时、分钟和秒,使用方法NUMTODSINTERVAL (1,’second’),增加1秒;NUMTODSINTERVAL (1,’hour),增加1小时

l          加一个简单的数来增加天

l          使用ADD_MONTH内置函数增加月和年

不建议使用NUMTOYMINTERVAL函数,其原因与这个函数如何处理月末日期有关。

ADD_MONTH实际上会为我们完成日期的“舍入”。如31日的增加一个月,而且下个月不足31天,会返回下个月的最后一天。另外,向一个月的最后一天增加1个月会得到下一个月的最后1天。如平年228331

NUMTOYMINTERVAL则可能会报出非法日期的信息。

 

得到两个日期的差

使用MONTHS_BETWEEN内置函数将这个数转换为年数和月数。另外,使用trunc得到两个日期间隔月数中整数部分,再使用add_months内置函数将dt1 增加12个月。再从两个日期中较大者,减去这个计算的得到的日期,从而得到两个日期之间的天数和小时数

 

select numtoyminterval(months_between(dt2,dt1),’month’) years_months,

         numtodsinterval(dt2 – addmonths(dt1, trunc(months_between(dt2,dt1))), ‘day’) days_hours

from (select to_date(’29-feb -2000 01:02: 03’ , ‘dd-mon-yyyy hh24:mi:ss’) dt1,

select to_date(’15-mar-2000 01:02: 03’ , ‘dd-mon-yyyy hh24:mi:ss’) dt2

from dual )

结果:

1年、15天、10小时、20分钟、30

 

TIMESTAMP,指定小数位个数。

得到两个 TIMESTAMP之差,DATETIMESTAMP的最显著差别,DATE相减是一个NUMBER,但TIMESTAMP相减结果是一个INTERVAL

类似上边,只是不需要,numtodsinterval函数,但问题是,这样会丢失小数秒。作者认为,显示有年和月的信息时,TIMESTAMP的真实性已经被破坏,一年本身的长度就不一定,如果有年月信息,毫秒级的损失是可以接受的。

 

INTERVAL YEAR(n) TO MONTH

n可为0 – 9,默认2

创建52月的时间间隔

select numtoyminterval(5,’year’) + numtoyminterval(2, ‘month’) from dual

 

INTERVAL DAY(n) TO SECOND(m)

n可为0 – 9,默认2m可为0 – 9,默认6

创建方法类似,用numtodsinterval

 

LOB类型

表中的LOB实际上只是指向lobindexlobindex再指向LOB本身的各部分。为了得到LOB中的NM字节,要对表中的指针(LOB定位器)解除引用,遍历lobindex结构来找到所需的数据块(chunk),然后顺叙访问。这使得随机访问LOB的任何部分都能同样迅速,无需从头遍历。

 

Table lobindex LobSegement.

Oracle8开始,不允许lobindexLobSegmentb不在同一个表空间中。对于小于4000字节的LOB,可能内联,或者存储在表中,这种情况下,LOB数据会被缓存。

 

IN ROW子句

控制LOB数据是否总与表分开存储(存储在LobSegment中),或是有时可以与表同一存储,而不放在logSegmentz中。lob(in_row ) store as (enable storage in row) 可用disable禁用。

 

chunkLOB的最小分配单元。而通常数据库的最小分配单元是块。

每个LOB实例(每个行外存储的LOB值)会占用至少一个CHUNK。一个CHUNK由一个LOB值使用。

另外,注意要让每个LOB实例对应的CHUNK数减至最少。主要是减小lobindex的索引出数。

 

PCTVERSION            LOB读一致性

RETENTION              PCTVERSION互斥,要求数据库使用自动undo管理

CACHE                        控制数据是否存储在缓冲区中

 

ROWID/UROWID类型

原来ROWID的行是不变的,插入时创建,直到删除。但后来情况有改变,有可能使ROWID改变,例如:

l          在分区表中更新一行的分区键,使这一行必须从一个分区移至另一分区

l          使用FLASHBACK TABLE命令将一个数据库表恢复到以前的某个时间点

l          执行MOVE操作以及许多分区操作,如分解或合并分区

l          使用ALERT TABLE SHRINK SPACE命令执行段收缩

 

 

以下部分看得不是很认真,略

第13章       分区

第14章       并行执行

第15章       数据加载和卸载

 

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目录回到顶部↑第1章 开发成功的Oracle应用 1 1.1 我的方法 2 1.2 黑盒方法 4 1.3 开发数据库应用的正确(和不正确)方法 8 1.3.1 了解Oracle体系结构 8 1.3.2 理解并发控制 14 1.3.3 多版本 19 1.3.4 数据库独立性? 25 1.3.5 “怎么能让应用运行得更快?” 41 1.3.6 DBA与开发人员的关系 45 1.4 小结 46 第2章 体系结构概述 47 2.1 定义数据库和实例 48 2.2 SGA和后台进程 53 2.3 连接Oracle 56 2.3.1 专用服务器 56 2.3.2 共享服务器 57 2.3.3 TCP/IP连接的基本原理 58 2.4 小结 61 第3章 文件 63 .3.1 参数文件 64 3.1.1 什么是参数? 65 3.1.2 遗留的init.ora参数文件 67 3.1.3 服务器参数文件 69 3.1.4 参数文件小结 75 3.2 跟踪文件 76 3.2.1 请求的跟踪文件 77 3.2.2 针对内部错误生成的跟踪文件 80 3.2.3 跟踪文件小结 83 3.3 警告文件 83 3.4 数据文件 86 3.4.1 简要回顾文件系统机制 86 3.4.2 Oracle数据库中的存储层次体系 87 3.4.3 字典管理和本地管理的表空间 91 3.5 临时文件 93 3.6 控制文件 95 3.7 重做日志文件 95 3.7.1 在线重做日志 96 3.7.2 归档重做日志 98 3.8 密码文件 100 3.9 修改跟踪文件 103 3.10 闪回日志文件 104 3.10.1 闪回数据库 104 3.10.2 闪回恢复区 105 3.11 DMP文件(EXP/IMP文件) 106 3.12 数据泵文件 107 3.13 平面文件 110 3.14 小结 111 第4章 内存结构 113 4.1 进程全局区和用户全局区 113 4.1.1 手动PGA内存管理 114 4.1.2 自动PGA内存管理 121 4.1.3 手动和自动内存管理的选择 131 4.1.4 PGA和UGA小结 132 4.2 系统全局区 133 4.2.1 固定SGA 137 4.2.2 重做缓冲区 137 4.2.3 块缓冲区缓存 138 4.2.4 共享池 145 4.2.5 大池 148 4.2.6 Java池 149 4.2.7 流池 150 4.2.8 自动SGA内存管理 150 4.3 小结 151 第5章 Oracle进程 153 5.1 服务器进程 153 5.1.1 专用服务器连接 154 5.1.2 共享服务器连接 156 5.1.3 连接与会话 157 5.1.4 专用服务器与共享服务器 163 5.1.5 专用/共享服务器小结 166 5.2 后台进程 167 5.2.1 中心后台进程 168 5.2.2 工具后台进程 175 5.3 从属进程 178 5.3.1 I/O从属进程 178 5.3.2 并行查询从属进程 179 5.4 小结 179 第6章 锁 181 6.1 什么是锁? 181 6.2 锁定问题 184 6.2.1 丢失更新 184 6.2.2 悲观锁定 185 6.2.3 乐观锁定 187 6.2.4 乐观锁定还是悲观锁定? 197 6.2.5 阻塞 198 6.2.6 死锁 201 6.2.7 锁升级 206 6.3 锁类型 206 6.3.1 DML锁 207 6.3.2 DDL锁 215 6.3.3 闩 218 6.3.4 手动锁定和用户定义锁 226 6.4 小结 227 第7章 并发与多版本 229 7.1 什么是并发控制? 229 7.2 事务隔离级别 230 7.2.1 READ UNCOMMITTED 232 7.2.2 READ COMMITTED 233 7.2.3 REPEATABLE READ 235 7.2.4 SERIALIZABLE 237 7.2.5 READ ONLY 239 7.3 多版本读一致性的含义 240 7.3.1 一种会失败的常用数据仓库技术 240 7.3.2 解释热表上超出期望的I/O 241 7.4 写一致性 244 7.4.1 一致读和当前读 244 7.4.2 查看重启动 247 7.4.3 为什么重启动对我们很重要? 250 7.5 小结 251 第8章 事务 253 8.1 事务控制语句 254 8.2 原子性 255 8.2.1 语句级原子性 255 8.2.2 过程级原子性 257 8.2.3 事务级原子性 260 8.3 完整性约束和事务 260 8.3.1 IMMEDIATE约束 260 8.3.2 DEFERRABLE约束和级联更新 261 8.4 不好的事务习惯 263 8.4.1 在循环中提交? 264 8.4.2 使用自动提交? 270 8.5 分布式事务 271 8.6 自治事务 273 8.6.1 自治事务如何工作? 273 8.6.2 何时使用自治事务? 276 8.7 小结 279 第9章 redo与undo 281 9.1 什么是redo? 281 9.2 什么是undo? 282 9.3 redo和undo如何协作? 285 9.4 提交和回滚处理 289 9.4.1 COMMIT做什么? 289 9.4.2 ROLLBACK做什么? 296 9.5 分析redo 297 9.5.1 测量redo 298 9.5.2 redo生成和BEFORE/AFTER触发器 300 9.5.3 我能关掉重做日志生成吗? 306 9.5.4 为什么不能分配一个新日志? 310 9.5.5 块清除 312 9.5.6 日志竞争 315 9.5.7 临时表和redo/undo 317 9.6 分析undo 321 9.6.1 什么操作会生成最多和最少的undo? 321 9.6.2 ORA-01555: snapshot too old错误 323 9.7 小结 334 第10章 数据库表 335 10.1 表类型 335 10.2 术语 337 10.2.1 段 337 10.2.2 段空间管理 339 10.2.3 高水位线 340 10.2.4 freelists 342 10.2.5 PCTFREE和PCTUSED 345 10.2.6 LOGGING和NOLOGGING 348 10.2.7 INITRANS和MAXTRANS 349 10.3 堆组织表 349 10.4 索引组织表 352 10.5 索引聚簇表 368 10.6 散列聚簇表 376 10.7 有序散列聚簇表 386 10.8 嵌套表 390 10.8.1 嵌套表语法 390 10.8.2 嵌套表存储 399 10.8.3 嵌套表小结 402 10.9 临时表 402 10.10 对象表 410 10.11 小结 418 第11章 索引 421 11.1 Oracle索引概述 422 11.2 B*树索引 423 11.2.1 索引键压缩 426 11.2.2 反向键索引 429 11.2.3 降序索引 435 11.2.4 什么情况下应该使用B*树索引? 437 11.2.5 B*树小结 448 11.3 位图索引 448 11.3.1 什么情况下应该使用位图索引? 449 11.3.2 位图联结索引 453 11.3.3 位图索引小结 455 11.4 基于函数的索引 456 11.4.1 重要的实现细节 456 11.4.2 一个简单的基于函数的索引例子 457 11.4.3 只对部分行建立索引 465 11.4.4 实现有选择的惟一性 467 11.4.5 关于CASE的警告 467 11.4.6 关于ORA-01743的警告 469 11.4.7 基于函数的索引小结 470 11.5 应用域索引 470 11.6 关于索引的常见问题和神话 472 11.6.1 视图能使用索引吗? 472 11.6.2 Null和索引能协作吗? 472 11.6.3 外键是否应该加索引? 475 11.6.4 为什么没有使用我的索引? 476 11.6.5 神话:索引中从不重用空间 483 11.6.6 神话:最有差别的元素应该在最前面 486 11.7 小结 490 第12章 数据类型 491 12.1 Oracle数据类型概述 491 12.2 字符和二进制串类型 494 12.2.1 NLS概述 494 12.2.2 字符串 497 12.3 二进制串:RAW类型 504 12.4 数值类型 506 12.4.1 NUMBER类型的语法和用法 509 12.4.2 BINARY_FLOAT/BINARY_DOUBLE类型的语法和用法 513 12.4.3 非固有数值类型 513 12.4.4 性能考虑 514 12.5 LONG类型 515 12.5.1 LONG和LONG RAW类型的限制 516 12.5.2 处理遗留的LONG类型 517 12.6 DATE、TIMESTAMP和INTERVAL类型 523 12.6.1 格式 523 12.6.2 DATE类型 525 12.6.3 TIMESTAMP类型 533 12.6.4 INTERVAL类型 541 12.7 LOB 类型 544 12.7.1 内部LOB 545 12.7.2 BFILE 557 12.8 ROWID/UROWID类型 559 12.9 小结 560 第13章 分区 561 13.1 分区概述 561 13.1.1 提高可用性 562 13.1.2 减少管理负担 564 13.1.3 改善语句性能 569 13.2 表分区机制 571 13.2.1 区间分区 571 13.2.2 散列分区 574 13.2.3 列表分区 579 13.2.4 组合分区 581 13.2.5 行移动 583 13.2.6 表分区机制小结 585 13.3 索引分区 586 13.3.1 局部索引与全局索引 587 13.3.2 局部索引 587 13.3.3 全局索引 594 13.4 再论分区和性能 610 13.5 审计和段空间压缩 617 13.6 小结 618 第14章 并行执行 619 14.1 何时使用并行执行 620 14.2 并行查询 622 14.3 并行DML 628 14.4 并行DDL 631 14.4.1 并行DDL和使用外部表的数据加载 632 14.4.2 并行DDL和区段截断 634 14.5 并行恢复 643 14.6 过程并行化 643 14.6.1 并行管道函数 644 14.6.2 DIY并行化 648 14.7 小结 652 第15章 数据加载和卸载 655 15.1 SQL*Loader 655 15.1.1 用SQLLDR加载数据的FAQ 660 15.1.2 SQLLDR警告 686 15.1.3 SQLLDR小结 686 15.2 外部表 687 15.2.1 建立外部表 688 15.2.2 处理错误 693 15.2.3 使用外部表加载不同的文件 697 15.2.4 多用户问题 697 15.2.5 外部表小结 698 15.3 平面文件卸载 698 15.4 数据泵卸载 708 15.5 小结 710 索引 711

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值