结构),而且如果有人正在修改数据结构,则不允许另外的人再来读取。对这些数据结构加闩的时间越长、越频繁,排队等待闩的进程就越多,等待队列也越长。你可能开始独占珍贵的资源。数据库中只要有一个应用表现不佳,就会严重地影响所有其他应用的性能。如果只一个小应用没有使用绑定变量,那么即使其他应用原本设计得很好,能适当地将已解析的SQL 放在共享池中以备重用,但因为这个小应用的存在,过一段时间就会从共享池中删除已存储的SQL。这就使得这些设计得当的应用也必须再次硬解析SQL。
不使用绑定变量是导致性能问题的一个主要原因,也是阻碍可扩缩性的一个重要因素。
不使用绑定变量的另外一个影响,就是安全性,容易受到“SQL注入”攻击。
Oracle 8.1.6 增加了一个新参数CURSOR_SHARING=FORCE。如果你愿意,这个特性会实现一个自动绑定器(auto-binder)。如果有一个查询编写为SELECT * FROM EMPWHERE EMPNO = 1234,自动绑定器会悄无声息地把它改写成SELECT * FROM EMP WHERE EMPNO = :x。这确实能动态地大大减少硬解析数,并减少前面讨论的库闩等待时间——但是它可能有一些副作用。从长远来看,要尽可能地使用绑定变量,而在需要时才使用常量,这才是正确的做法。
5)大池(large pool)
大池用于大块内存的分配,共享池不会处理这么大的内存块。
共享池根据LRU来管理内存,这对于缓存和重用数据很合适。大块内存分配则是得到一块内存后加以使用,然后就到此为止,没有必要缓存这个内存。
大池中分配的内存在堆上管理,与C语言通过malloc()和free()管理内存很相似。一旦“释放”了一块内存,它就能由其他进程使用。在共享池中,实际上没有释放内存块的概念。只是分配内存,然后使用,再停止使用而已。过一段时间,如果需要重用那个内存,Oracle会让你的内存块老化。
大池专门用于以下情况:
共享服务器连接,用于在SGA 中分配UGA 区。
语句的并行执行,允许分配进程间的消息缓冲区,这些缓冲区用于协调并行查询服务器。
备份,在某些情况下用于RMAN磁盘I/O 缓冲区。
6)Java池(java pool)
用于支持在数据库中运行Java。
7)流池(stream pool)
用于支持流(一个数据库共享/复制工具)。
对 SGA 整体大小影响最大的参数如下:
JAVA_POOL_SIZE:控制Java 池的大小。
SHARED_POOL_SIZE:在某种程度上控制共享池的大小。
LARGE_POOL_SIZE:控制大池的大小。
DB_*_CACHE_SIZE:控制各个可用的缓冲区缓存的大小。
LOG_BUFFER:在某种程度上控制重做缓冲区的大小。
SGA_TARGET:Oracle 10g及以上版本中用于自动SGA内存管理。
SGA_MAX_SIZE:用于控制数据库启动并运行时SGA可以达到的最大大小。
可以通过查询v$sgainfo视图来查看SGA各个组件大小,以及是否可以调整(RESIZEABLE)。
如果采用手动SGA内存管理,需要设置上述各个参数;
如果采用自动SGA内存管理,只需把SGA_TARGET 参数设置为所需的SGA大小,数据库实例会根据工作负载条件在运行时分配和撤销(释放)各个SGA 组件。
关闭数据库时,数据库会把各个SGA组件大小通过一些首部带下划线参数(__DB_CACHE_SIZE、__JAVA_POOL_SIZE、__LARGE_POOL_SIZE 和__SHARED_POOL_SIZE等)记录到存储参数文件(SPFILE)中,并在启动时再使用这些值来设置各个区的默认大小。
另外,如果知道上述4个区中某个区的最小值,那么除了设置SGA_TARGET 外,还可以设置这个参数。实例会使用你的设置作为下界(即这个区可能的最小大小)。
11g之后,Oracle提供了自动内存管理,只需要设置memory_target这一个参数,Oracle自动确定所有内存区大小。这种情况下,SGA_TARGET和PGA_AGGREGATE_TARGET这2个参数就被用来设定下界。
Oracle会把SGA和PGA的最优设置存储到spfile的__sga_target和__pga_aggregate_target这2个参数中。
不论是使用自动内存管理还是手动内存管理,各个池的内存以一种称为颗粒(granule)的单位来分配。
通过查询V$SGA_DYNAMIC_COMPONENTS,可以查看各个池所用的颗粒大小。例如:
select component, granule_size from v$sga_dynamic_components;