【每日一摩斯】-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文本是不是真的是完全相同(以至于他们可以被共享),包括:

语句中引用的所有的对象名必须都被解析成实际相同的对象。

发起语句的session中的optimizer相关的参数应该一致。

绑定变量的类型和长度应该是"相似的"。(这里不做详细讨论,但是类型和长度的不同确实会导致语句被分为不同的版本)

发起语句的NLS (National Language Support)设置必须相同。

(6)、语句的版本

正如之前在'Sharable SQL'中描述的,如果两个语句字面上完全相同但是又不能被共享,则会对相同的语句产生不同的'version',即版本。如果Oracle要匹配一个包含多个版本的语句,它将不得不检查每一个版本来看它们是不是和当前被解析的语句完全相同。所以最好用以下方法来避免高版本数(high version count)。

客户端使用的绑定变量最大长度需标准化。

如果有大量的schema会包含相同名字的对象,那么避免使用一个相同的SQL语句。比如:SELECT xx FROM MYTABLE;
并且每个用户都有一个自己的MYTABLE 的情况。

在Oracle 8.1可以将_SQLEXEC_PROGRESSION_COST设置成'0'。

(7)、Library Cache和Shared Pool latches

shared pool latch是用来保护从shared pool中分配和释放内存的关键性操作。

Library cache latche(以及Oracle 7.1中的library cache pin latch)是用来保护library cache中的操作。

所有的这些Latch都是潜在的资源争用的对象,latch gets发生的次数直接受到shared pool中活动(activity)个数的影响,特别是parse操作。任何减少latch gets或者shared pool中活动(activity)个数的尝试都有助于提高性能和可扩展性。

To Be Continued ...

时间: 2024-09-17 04:15:00

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

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

CURSOR_SHARING 参数 (8.1.6 以上)        这个参数需要小心使用.如果它被设为FORCE,那么Oracle会尽可能用系统产生的绑定变量来替换原来SQL中的literals部分.对于很多仅仅是literal不一样的相似的语句,这会让它们共享cursor.这个参数可以在系统级别或者session级别动态设置: ALTER SESSION SET cursor_sharing = FORCE; 或者 ALTER SYSTEM SET cursor_sharing = FOR

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

下面来谈一谈系列1中讲到的Literal SQL和Shared SQL的比较. 首先是Literal SQL: 在有完整的统计信息并且SQL语句在predicate(限定条件)中使用具体值时,基于成本的优化器 (CBO)能工作的最好.比较下面 的语句: SELECT distinct cust_ref FROM orders WHERE total_cost < 10000.0; 和 SELECT distinct cust_ref FROM orders WHERE total_cost <

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

Flushing(清空) SHARED POOL        在使用大量literal SQL的系统中,shared pool随时间推移会产生大量碎片进而导致并发能力的下降.Flushing shared pool能够使得很多小块碎片合并,所以经常能够在一段时间内恢复系统的性能.清空之后可能也会产生短暂的性能下降(补充:因为需要做第一次的硬解析),因为这个操作同时也会把没造成shared pool碎片的共享SQL也清除了.清空shared pool的命令是: ALTER SYSTEM FLUS

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

减轻Shared Pool负载 Parse一次并执行多次        在OLTP类型的应用中,最好的方法是只让一个语句被解析一次,然后保持这个cursor的打开状态,在需要的时候重复执行它.这样做的结果是每个语句只被Parse了一次(不管是soft parse还是hard parse).显然,总会有些语句很少被执行,所以作为一个打开的cursor维护它们是一种浪费.        请注意一个session最多只能使用参数:open_cursors定义的cursor数,保持cursor打开会增加

[转载】&amp;mdash;&amp;mdash;故障排除:Shared Pool优化和Library Cache Latch冲突优化 (文档 ID 1523934.1)

原文链接:https://support.oracle.com/epmos/faces/DocumentDisplay?_adf.ctrlstate=23w4l35u5_4&id=1523934.1用途   提出问题,得到帮助并分享您的心得   排错步骤   什么是shared pool?   专用术语   Literal SQL   Hard Parse(硬解析)   Soft Parse(软解析)   完全相同的语句?   Sharable SQL   语句的版本   Library Cac

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

使用SQL 查看Shared Pool问题        这一章节展示了一些可以用来帮助找到shared pool中的潜在问题的SQL语句.这些语句的输出最好spool到一个文件中. 注意:这些语句可能会使latch竞争加剧,我们在上面的"使用 V$ 视图 (V$SQL 和 V$SQLAREA)" above. 查找literal SQL SELECT substr(sql_text,1,40) "SQL",                count(*) ,  

shared pool latch和library cache latch

shared pool latch和library cache latch    >                                   >                                                                                                                                                                           

【每日一摩斯】-Fundamentals of the Large Pool

以下内容介绍从Oracle 8引入的'Large Pool'. 什么是Large Pool(翻译过来叫"大池")?        大池是SGA中一块类似于shared pool的区域,但是它的使用又有严格的限制,仅有几种类型和大小的内存能够在这个池中分配.        大池的内存不是来自于shared pool,而是直接来自于SGA,因此需要在实例启动时增加共享内存的容量.        大池的大小由LARGE_POOL_SIZE参数决定,可以分配的最小内存chunk由LARGE_P

【每日一摩斯】-RAC and Sequences (853652.1)

序列有四种组合: a. CACHE + NOORDER b. CACHE + ORDER c. NOCACHE + NOORDER d. NOCACHE + ORDER 即使在单例配置下,当有大量的sequence需要产生的时候,性能压力和存储sequence值的行锁定代价相关. NOCACHE与CACHE的性能       当使用cache时,dictionary cache(row cache)仅仅当出现新的水位线时才会更新一次.例如当cache是20,nextval第一次请求时,dicti