Oracle数据库之常见名词解析


Oracle SQL 高级编程》

         [email protected]

数据库: (database)物理操作系统文件或磁盘(disk)的集合。使用 Oracle 10g 的自动存储管理(Automatic Storage ManagementASM)或 RAW 分区时,数据库可能不作为操作系统中单独的文件,但定义仍然不变。而数据库只是一个文件集合(包括数据文件、临时文件、重做日志文件,控制文件)

数据库实例:归属于内存结构,一个实例由系统全局内存区域(system global area ,SGA) 以及一系列的后台进程组成.这里可以维护易失的、非持久性内容(有些可以刷新输出到磁盘)。就算没有磁盘存储,数据库实例也能存在.

 

用户跟服务器之间的进程管理:



 

 <!--[if !mso]> <style> v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} </style> <![endif]-->

 

专用服务器进程:如前所述,在我登录时,Oracle 总 会为我创建一个新的进程。这通常称为专用服务器配置,因为这个服务器进程会在我的会话生存期中专门为我服务。对于每个会话,都会出现一个新的专用服务器, 会话与专用服务器之间存在一对一的映射。

 

 

共享服务器Oracle 还可以接受另一种方式的连接,这称为共享服务器(shared server),正式的说法是多线程服务器(Multi-Threaded Server)或 MTS。如果采用这种方式,就不会对每条用户连接创建另外的线程或新的 UNIX 进程。在共享服务器中,Oracle 使用一个“共享进程”池为大量用户提供服务。共享服务器实际上就是一种连接池机制。(oracle采用调度器完成客户端进程的分配,完成客户端进程与服务器进度的通信)

 



 

 

 

SGA:内存区域有限,采用最近最少使用(Last Recently Used,LRU)算法来保留解析的sql语句,为高校的使用共享池,所写的语句最好是可以共享的

软解析:执行sql语句之前,必须被解析并载入到高速缓存区域中,解析过程包括:①验证语句语法②检验提及的对象③确认对象权限,如果这些都通过了,接下来就看该语句是否执行过,如果是oracle会在库高速缓存区域提取信息直接重用

硬解析:如果语句没有执行过,oracle就会执行所有的执行工作来为当前的语句生成执行计划,并把它存储到库高速缓存区域,以便重用.然后执行该语句(在执行解析后是sql语句之前,需要对该语句的所有信息进行收集,需要对数据字典进行一系列的查询,所以硬解析比软解析要做更多的工作)

什么是完成相同的sql语句:

1.   select * from emp where id = 3;

2.   SELECT * FROM EMP WHERE ID = 3;

3.   select /* 注释*/ * from emp where id = 3;

分析:尽管上述3条语句得到的结果相同,但oracle 还是会进行3次硬解析.oracle在判断是否是相同语句时,把sql语句当成字符串,进行字符串的hash值比较,而每个语句的hash值作为存在库高速缓存区域的 关键字

如下语句可以查看详细信息:

Select sql_text ,sql_id , child_number,hash_value,address,executions from v$sql where upper(sql_text) like ‘%emp%’;

 

这就是为什么在sql语句中采用绑定变量要由于常量的原因,使用绑定变量时,oracle缓存了绑定了变动变量,即使改变了绑定变量的值,oracle还是可以共享这个语句

上面的语句优化成如下:
variable v_dept number;

exec :v_dept :=0;

Select * from emp where id = :v_dept;

 

锁存器:oracle为了读取存放在库高速缓存或者其他内存结构信息中的信息时必须获得的一种锁,锁存器可以保护库高速缓存避免两个同时进行的回话修改,或者一个会话正要读取的信息被另外一个会话修改而导致的损坏,锁存器与典型的锁不一样,他并不是一个队列.

锁存器的工作原理:oracle为了检查你要执行的SQL语句是否存在,那么它就要在库高速缓存中获取一个锁存器,如果锁存器是空闲的,它将获取该锁存器做它需要做的工作,然后释放锁存器.如果已经被占用,oracle采取一种自旋的方式。

C1:cpu 我能获得锁了吗?

C2:cpu我能获得锁了吗?

Oracle 积极使用cpuc1,c2进行检查,c1.c2的实际查询是挂起的.在锁存器可用之前不会做任何事情,如果一段时间的自旋之后锁存器还是不可用(_spin_count指定的参数,默认是2000),该请求会被暂时停止.你的回话也不得不排到别的需要使用cpu的会话后面去,它需要再次等待它使用CPU的时间来检查锁存器是否可用,这个迭代过程会不断重复直到锁可用.那么你不仅要排队等待锁存器可用,而且当你在排队等待返回CPU中再次检查锁存器是否可用的时候另外一个会话完全有可能获得锁存器,如果有很多会话同时需要获得锁存器,就会非常耗费时间.锁存器是串行的,Oracle需要获得锁存器的频率越高,就越有可能发生争夺,你也就不得不等待更长的时间,同样要减少锁存器(硬解析)是非常关键的



 

 

数据访问:生成执行之前oracle优化器会通过2种方式来确定数据的访问,①全表扫描,就是读取多个块数据到IO运算中.②:索引扫描,首先扫描叶子块以取得特定的id,然后利用这些ID来访问父表取得实际的行数据,这些访问都是通过单块来完成的

 

全表扫描:当对一个对象进行全表扫描时,与该对象相关的所有数据块都必须取出来并进行处理,以确定块中所包含的数据行是否是你查询所需要 ,请记住Oracle必须将整个数据块读到内存中以取得这个块中所存储的数据行的数据.(访问数据块的数目以及舍弃的数量越大,全表扫描的成本也就越高)

 

高水位线:标出了表中最后一块有数据库写入的数据块,当进行全表扫描的时候,oracle将最多读取到位于表中高水位线的数据块



 

 

索引扫描:索引是建立在表中的一个或多个列的表达式上,将列值和行编号(rowid)一起存储,在索引中还保存着一些其他信息,但对你来说仅需要关心列值和行编号即可,rowid是一个用来唯一标记表中行的伪列,它是物理表中行数据的内部地址,它包含两个地址,①:数据库表中包含该行的块在数据库文件的地址.:数据行自身在数据块的地址.

 

事务:一个事务可以由多个DML(数据操作 insert,delete,update)语句组成,但只能含有一个数据定义语言(DDL)语句,DDL语句会产生一次隐士提交,同时也会提交任何值钱没有提交的工作.

事务的ACID:

原子性(Atomicity):事务中的所有任务都必须执行或者都不执行,不存在部分事务.

一致性(Consistency):事务将数据库从一个一致性状态带到另一个一致性状态

隔离性(Isolation):一个事务所带来的影响直到该事务提交之前对其他事务来说都是不可见的.

持久性(Durability):经过提交的事务所进行的修改都是永久的

 

解决丢失更新oracle采用锁机制来解决.

悲观锁:认为我读取的这行数据肯定会被改,那么当我读取的时候就锁定这行数据.

      Sql: select xxx from xxx for update nowait;

乐观锁:认为没有人会修改我读取的行数据,只有在修改的时候加上锁.解决办法,可以在表中添加1NUMBER DATE/TIMESTAMP ,可以由应用维护这一列,更新记录时将LAST_MOD 列的值设置为 SYSTIMESTAMP;也可以由触发器/存储过程来维护。如果让应用维护 LAST_MOD,这比基于触发器的方法表现更好,因为触发器会代表 Oracle 对修改增加额外的处理.

   Update xxx set xxx from xxx id = 1 and last_mod = xxx;

猜你喜欢

转载自whatisjavabean.iteye.com/blog/2003465