日期:2014-05-16  浏览次数:20445 次

【每日一摩斯】-Shared Pool优化和Library Cache Latch冲突优化 (1523934.1)-系列1

什么是Shared Pool?

       Oracle的实例主要包括共享内存(主要是SGA,还有PGA)和Background Processes,其中SGA中又包括了Shared Pool、Buffer Cache、Redo Log Buffer以及其它一些内存区。

       Oracle在SGA的一个特定区域中保留SQL语句、Package是、对象信息以及其它一些内容,这就是Shared Pool。这个共享内存区域是由一个复杂的cache和heap manager 构成的。它需要解决三个基本问题:

1. 每次分配的内存大小是不一致的,从几个字节到上千个字节;

2. 因为shared pool的目的是为了最大化共享信息,所以不是每次一个用户用完之后就可以释放这段内存(在传统的heap manager方式会遇到这个问题)。内存中的信息可能对于其他session来说是有用的——Oracle并不能事先知道这些内容是否会被再次用到;

3. Shared pool中的内容不能被写入到硬盘区域中,这一点和传统cache是不一样的。只有“可重建”的信息可以被覆盖,因为他们可以在下次需要时重建。

       基于这些背景,我们就可以理解shared pool的管理是一件非常复杂的事情。

       MOS介绍这部分知识时提到了若干术语:

(1)、Literal SQL(翻译过来又叫字面SQL)

一个Literal SQL语句是指在predicate中使用具体值,而不是使用绑定变量,即不同的执行语句使用的具体值可能是不一样的。

例1:应用程序使用了:

SELECT * FROM emp WHERE ename='CLARK';

而不是:

SELECT * FROM emp WHERE ename=:bind1;

例2: 以下语句不用绑定变量但是也不会被认为是literal SQL,因为这个语句可以被多次执行共享。

SELECT sysdate FROM dual;

例 3: 如果整个应用都是用相同的值'2.0'来检查'version'的话,那么这个语句可以被认为是可以共享的。

SELECT version  FROM app_version WHERE version>2.0;

(2)、Hard Parse(硬解析)

简单讲,一个新的SQL被执行,但又不在Shared Pool中,那么它将被完整地解析一次(这里的过程其实很多,主要包括语法语义检查、执行计划的解读与选择),这其中牵扯到访问dictionary cache、Shared pool latch的获取、执行计划的计算等等,其中执行计划的计算是最耗CPU资源的。

(3)、Soft Parse(软解析)

与硬解析相对的,如果一个session请求的一个已经在Shared pool的SQL语句,无需进行上述执行计划计算等这些步骤,就被称为‘Soft Parse',对于应用来说,它只需请求解析这个语句。(实际上还有所谓的软软解析)。

(4)、完全相同的语句?

如果两个SQL语句的含义相同但是没有使用相同的字符,那么Oracle认为它们是不同的语句。比如SCOTT在一个Session中提交的这两个语句:

SELECT ENAME from EMP;

SELECT ename from emp;

尽管它们实际上是相同的,但是因为大写字母‘E’和小写字母'e'的区别,他们不会被认为是完全相同的语句。

为什么有如上说法呢?因为Oracle会将一个SQL转换为ASCII值,然后利用HASH函数计算其对应的hash值,到Library Cache中找是否有对应于此唯一HASH值的bucket,如果有比较bucket中是否存在该SQL,若没有则执行硬解析。那么大小写的ASCII是不同的,因此要求是case-insensitive。

(5)、Sharable SQL

如果是两个不同的session发起了完全相同的SQL语句,这也不意味着这个语句是可以共享的。比如说:用户SCOTT下有一个表EMP,发起了下面的语句:

SELECT ENAME from EMP;

用户FRED 有一个自己的表也叫EMP并且发起相同的语句:

SELECT ENAME from EMP;

尽管语句完全一样但是由于需要访问的EMP表是不同的对象,所以需要对这条语句产生不同的版本。

这里MOS没有展开说,实际上这里说到的两个用户,其对应于两个schema,我们知道不同的schema中有不同的对象,不同schema内的对象若被其它用户访问,需要DBA或该用户赋予相关权限。另外,SQL硬解析时需要将对象进行名转换,比如讲同义词转换为实际的对象,我想这里SCOTT执行的SELECT ENAME from EMP应该转换成SELECT ENAME from SCOTT.EMP。因此这两个SQL是不同的

有很多条件来判断两个完全一致的SQL文本是不是真的是完全相同(以至于他们可以被共享),包括: