Oracle共享池

共享池

SGA中的共享池(shared pool)是由库高速缓存(library cache)和数据字典高速缓存(data dictionary cache)两部分所组成。服务器进程将SQL或者PL/SQL语句的正文和编译后的代码以及执行计划都放在共享池的库高速缓存中,在进行编译时,服务器进程首先会在共享池中搜索是否有相同的SQL或者PL/SQL语句,如果有就不进行任何后续的编译处理,而是直接使用已存在的编译后的代码和执行计划。

一、库高速缓存
注意:

库高速缓存包含了共享SQL区和共享PL/SQL区两部分,它们分别存放SQL和PL/SQL语句以及相关的信息。在Oracle 11g和Oracle 12c中,库高速缓存还可以包括SQL和PL/SQL的执行结果,这样其他使用相同SQL或PL/SQL语句的进程就可以直接共享这些结果,提高了效率。

引入库高速缓存的目的是共享SQL或PL/SQL代码。
1.SQL或PL/SQL语句要是能共享的通用代码;
2.库高速缓存要足够大;

解释一下:

SQL或PL/SQL语句要是能共享的通用代码

因为Oracle是通过比较SQL或PL/SQL语句的正文来决定两个语句是否相同的,只有当两个语句的正文完全相同时,Oracle才能重用已存的编译后的代码和执行计划。如果只是字母大小写不一样,那么字母大小写Oracle会自动转换,而且多余的空格或者制表键Oracle也会自动地压缩。
例如:

SELECT * FROM emp WHERE sal >= 10000;
SELECT * FROM emp WHERE sal >= 12000;

上面代码因为SQL语句的不同的,所以不是能共享的,那么我们可以使用通用代码来达到共享;我们可以通过绑定变量的方式:

SELECT * FROM emp WHERE sal >= :g_sal;

因为变量不是在编译阶段而是在运行阶段赋值的。

库高速缓存要足够大

为了能够共享SQL或PL/SQL的代码,库高速缓存要足够大,因为这样,那些可以共享的SQL或者PL/SQL代码才不会被很快地淘汰出内存。

注意:

Oracle并没有给出直接设置库高速缓存大小的方法,只能通过设置共享池的大小来间接地设置库高速缓存的大小。

Oracle是如何有效地管理库高速缓存的?

Oracle是使用LRU算法来实现对库高速缓存管理的。
LRU(最近最少使用)可以理解为:最近这段时间最少访问的,最少使用。
这里我不做说明,找了个网上大佬的博客,为了让我下次看到这里方便理解。
https://www.cnblogs.com/geyifan/p/3817454.html
值得一提的:Redis的回收算法也是LRU;

二、数据字典高速缓存

当Oracle在执行SQL语句时,服务器进程将把数据文件、表、索引、列、用户和其他的数据对象的定义和权限的信息放入数据字典高速缓存。如果在这之后,有用户进程需要同样的信息,如表和列的定义,那么所有的这些信息都将从数据字典高速缓存中获得。
我们都知道,相比SQL语句,表和列的定义等重用的机会更多,同样的,为了达到共享这些信息的目的,数据字典高速缓存应该尽量设置的大一些。

注意:

Oracle并没有给出直接设置数据字典高速缓存大小的方法,只能通过设置共享池的大小来间接地设置数据字典高速缓存的大小。

三、如何设置共享池的大小

在i9之前,可以通过修改参数文件中的SHARED_POOL_SIZE的值来改变共享池的大小,但一定要重启数据库;而i9之后,可以使用命令来改变共享池的大小,但是但是所改变共享池的大小受限于SGA_MAX_SIZE参数

ALTER SYSTEM SET SHARED_POOL_SIZE = 250M
注意:

即使把共享池设置得足够大且所使用的SQL或PL/SQL语句是能共享的代码,Oracle并不能一定使用共享池中的代码。
例如:
当有用户修改了某个对象的定义之后,所有使用这个对象的共享池中的代码全部被Oracle设置为无效,因此在使用时必须重新编译。

你可能感兴趣的:(数据库,oracle,数据库,sql)