简单分析shared pool(二)

对于shared pool的学习,发现越尝试去了解,发现自己对它越不了解。里面的东西很杂。
自己想用几个问题来作为引子来说明更加会有条理一些。
shared pool的大小设置
对于shared pool的大小设置,从早期版本到现在一直都带有争论。
从操作上来说,需要设置shared_pool_size就可以了,如果启用了sga_target或者11g里的memory_target,那shared pool的大小设置都是自动管理的了。
还有shared_pool_reserved_size会在shared pool中保留一块固定的内存区域留给一些大对象使用,它的空间是独立的。
从理论上来说,shared pool中含有的free list,或者是bucket,上面有很多的chunk,如果一条sql语句进入library cache,需要申请一块新的内存空间的时候,就需要遍历free list,如果free list很长,在这个过程中也会持有latch,直到解析完成。所以从这个角度来说,设置小的shared pool可能能减少latch的持有时间,但是反过来说,如果shared pool太小,可能空间老是紧张,会有频繁的换入换出的chunk操作,无论扫描还是对chunk的管理都是需要持有latch的,都在一定程度上影响性能,如果设置shared Pool大一些,可能能够延缓一下latch的争用,但是如果随着free list中的碎片增多。导致free类型的chunk越来越多,最后也还是会造成争用。

shared pool的sub pool
这个问题可以从第一个问题得到延伸,如果单纯设置shared pool过大存在问题,设置太小也有问题,从oracle的设计角度来说,就根据系统的情况,可以指定sub pool,比如我的机器配置足够好。可以设置多个sub pool来,每个sub pool都是都有单独的free list,和保留区域,但是彼此之间还是通过latch来并发共享。这样也可以在一定程度上提高shared pool的性能。
11g开始,每个sub pool都为512M
可以通过隐含参数来查看当前的库中sub pool的设置。

  1* select a.ksppinm,b.ksppstvl from x$ksppi a,x$ksppsv b where a.indx=b.indx and a.ksppinm='_kghdsidx_count'
SQL> /

KSPPINM              KSPPSTVL
-------------------- ----------------------------------------
_kghdsidx_count      1

我本地的环境配置比较差,目前只有一个sub pool,因为shared_pool的大小是200M,没有足够的资源。
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
shared_pool_reserved_size            big integer 10M
shared_pool_size                     big integer 200M

关于绑定变量和硬解析
提到shared pool,不得不提绑定变量,在线业务系统中是很关键的一个指标。
可以举一个例子来简单说明一下。
首先创建一个表test_var,然后传入两个变量值,类型不同,看看执行的情况。
create table test_var as select object_id id,object_name name from user_objects where rownum
update test_var set name='aaa' where rownum
update test_var set name='bbb' where name!='aaa';  --修改另外一条数据

SQL> alter system flush shared_pool;

System altered.

SQL> variable name varchar2(100);
SQL> exec :name:='aaa';

PL/SQL procedure successfully completed.

SQL> select *from test_var where name=:name;

        ID NAME
---------- --------------------------------------------------------------------------------------------------------------------------------
     21014 aaa

运行语句之后,查看sql_id,和hash值,从v$sqlarea中可以查看version_count,如果发生了硬解析,version_count就会递增。
SQL> select sql_id,hash_value,address,child_address from v$sql where sql_text like 'select *from test_var%';

SQL_ID        HASH_VALUE ADDRESS          CHILD_ADDRESS
------------- ---------- ---------------- ----------------
3vm96qwzm0mg2 1060130274 000000006B751178 0000000069764850

SQL> col sql_text format a50
SQL> select sql_text,version_count from v$sqlarea where sql_text like 'select *from test_var%';

SQL_TEXT                                           VERSION_COUNT
-------------------------------------------------- -------------
select *from test_var where name=:name                         1

然后再来赋另外一个值,看看version_count会不会递增。

SQL> exec :name:='bbb';

PL/SQL procedure successfully completed.

SQL> select *from test_var where name=:name;

        ID NAME
---------- --------------------------------------------------------------------------------------------------------------------------------
     15287 bbb

SQL> col sql_text format a50
SQL> select sql_id,hash_value,address,child_address from v$sql where sql_text like 'select *from test_var%';

SQL_ID        HASH_VALUE ADDRESS          CHILD_ADDRESS
------------- ---------- ---------------- ----------------
3vm96qwzm0mg2 1060130274 000000006B751178 0000000069764850

SQL>
SQL> select sql_text,version_count from v$sqlarea where sql_text like 'select *from test_var%';

SQL_TEXT                                           VERSION_COUNT
-------------------------------------------------- -------------
select *from test_var where name=:name                         1

可以看到,没有任何的变化,说明绑定变量起作用了,没用再次硬解析。
来改一下数据类型,看看效果。我把变量类型从varchar2改为了char

SQL> variable name char(3);
SQL> exec :name:='aaa';

PL/SQL procedure successfully completed.

SQL> select *from test_var where name=:name;

        ID NAME
---------- --------------------------------------------------------------------------------------------------------------------------------
     21014 aaa

SQL> select sql_text,version_count from v$sqlarea where sql_id='3vm96qwzm0mg2'
  2  /

SQL_TEXT                                           VERSION_COUNT
-------------------------------------------------- -------------
select *from test_var where name=:name                         2

SQL> select sql_id,hash_value,address,child_address from v$sql where sql_text like 'select *from test_var%';

SQL_ID        HASH_VALUE ADDRESS          CHILD_ADDRESS
------------- ---------- ---------------- ----------------
3vm96qwzm0mg2 1060130274 000000006B751178 0000000069764850
3vm96qwzm0mg2 1060130274 000000006B751178 000000006A039F40

不同之处就是child_address,说明走了两次硬解析。
可以想象如果在繁忙的业务系统中如果大量的sql语句走反复解析的话,会耗费大量的cpu资源和时间。导致系统性能的下降。

时间: 2024-08-02 17:25:18

简单分析shared pool(二)的相关文章

简单分析shared pool(三)

提到shared pool,都会不由得和sql语句的解析过程联系起来,因为shared pool所做的主要工作就是解析sql语句,生成执行计划,在之前的两篇中对于shared pool的存储进行了简单的分析,在10g,11g都是保留了255个bucket,可见这个值还是一个最优的默认值了. 在第二篇中分析了一些关于绑定变量的内容,一般一提到sql语句的解析,都会多多少少提到绑定变量,其实有时候也给我们带来一些困扰,其实直接使用绑定是一种情况,还可以通过其它的方式间接使用. 比如下面的例子. de

简单分析shared pool(一)

oracle中的shared pool很重要,但是感觉知之甚少.今天想在原来的认识上能够有一点更深入的了解. 简单做了一个总结. 首先是转储一下shared pool共享内存的内容. SQL> alter session set events 'immediate trace name heapdump level 2'; Session altered. 这个步骤会得到一个trace文件.简单的换算一下,就得到了trace文件的大体信息. SQL> select sid from v$mys

关于shared pool的深入探讨(二)

关于shared pool的深入探讨(二) Sunday, 2004-08-22 21:23 Eygle       link: http://www.eygle.com/internal/shared_pool-2.htm我们继续把前面的问题展开一下. 其实我们可以从数据库内部监控shared pool的空间碎片情况.这涉及到一个内部视图x$ksmsp X$KSMSP的名称含义为: [K]ernal [S]torage [M]emory Management [S]GA Hea[P]其中每一行

网口扫盲二:Mac与Phy组成原理的简单分析

网口扫盲二:Mac与Phy组成原理的简单分析 1. general 下图是网口结构简图.网口由CPU.MAC和PHY三部分组成.DMA控制器通常属于CPU的一部分,用虚线放在这里是为了表示DMA控制器可能会参与到网口数据传输中. 对于上述的三部分,并不一定都是独立的芯片,根据组合形式,可分为下列几种类型: CPU集成MAC与PHY; CPU集成MAC,PHY采用独立芯片; CPU不集成MAC与PHY,MAC与PHY采用集成芯片; 本例中选用方案二做进一步说明,因为CPU总线接口很常见,通常都会做

shared pool系列二:free lists/shared pool lru list

介绍free lists及shared pool lru list. Shared pool中chunk的分配 1.shared pool中的chunk的大小是不一样的,但是是连续的 2.因为chunk是分配的最小单元,因此session需要给对象分配空间的时候,会以chunk为单位进行申请 3.可用的chunk(free)会形成一个链表 feee lists,便于进行分配的时候,可以通过遍历链表寻找到可用的适合的chunk,链表是chunk进行组织和管理的一种方式 4.一个可用的chunk链表

shared pool 深度解析1+

原文整理自网络 1. 深入Shared Pool   Oracle数据库作为一个管理数据的产品,必须能够认出用户所提交的管理命令(通常叫做SQL语句),从而进行响应.认出的过程叫做解析SQL语句的过程,响应的过程叫做执行SQL语句的过程.解析是一个相当复杂的过程,它要考虑各种可能的异常情况,比如SQL语句涉及的对象不存在.提交的用户没有权限等.而且,还需要考虑如何执行SQL语句,采用什么方式去获取数据等.解析的最终结果是要产生Oracle自己内部的执行计划,从而指导SQL的执行过程.可以看到,解

共享池的调整与优化(Shared pool Tuning)

--======================================= -- 共享池的调整与优化(Shared pool Tuning) --=======================================       共享池(Shared pool)是SGA中最关键的内存片段,共享池主要由库缓存(共享SQL区和PL/SQL区)和数据字典缓存组成.其中库缓存的作用是存 放频繁使用的sql,pl/sql代码以及执行计划.数据字段缓存用于缓存数据字典.在内存空间有限的容量下

shared pool 深度解析3(subpool)+

我们知道,从Oracle 9i开始,Shared Pool可以被分割为多个子缓冲池(SubPool)进行管理,以提高并发性,减少竞争. Shared Pool的每个SubPool可以被看作是一个Mini Shared Pool,拥有自己独立的Free List.内存结构以及LRU List.同时Oracle提供多个Latch对各个子缓冲池进行管理,从而避免单个Latch的竞争(Shared Pool Reserved Area同样进行分割管理).SubPool最多可以有7个,Shared Poo

【每日一摩斯】-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 <