二 系统设定篇
一 避免动态重编译
什么是pl/sql的动态重编译
在某个Pl/sql程序中(假定为AP1)用到的对象被删除,修改或者重新生成了,那么AP1的状态就变成了INVALID,比如ap1过程调用到了ap2这个过程,ap2在一次编译中报错了,改完ap2并编译完后,ap1也就变成了invalid状态,
从oracle8开始,ap1执行的时候,会对他进行重新编译,只要没有编译错误ap1就可以继续执行
对ap1的重编译会占用一定的时间,所以应该尽量避免这种情况发生。为了避免这种情况,我们应当最大限度的去了解对象间的关联。以及别在过程中创建需要使用的对象等。
下面说说查看对象关联的方法。
第一种方法,使用utldtree
我们需要执行下面三步才能看到
第二种 直接看数据字典 user_dependencies
列名 |
列说明 |
NAME |
对象名称 |
TYPE |
NAME列的对系那个类型 |
REFERENCED_OWNER |
和NAME列的对象有关联的对象的所有者名字 |
REFERENCED_NAME |
与NAME列的对象有关联的对象的名称 |
REFERENCED_TYPE |
与NAME列的对象有关联的对象的类型 |
REFERENCED_LINK_NAME |
如果是远程对象,所使用的dblink的名字 |
二 让执行部分常驻内存
存储过程常驻内存,这个方法是把双刃剑,虽然能使用存储过程的调用速度加快,特别是在某个过程使用频率很高的情况下,但是如果过分的使用,则会增加共享池的负荷。所以pl/sql的优化主要还是集中在编程以及sql优化中,当某个过程调用频率到达一定程度才使用。当然如果某些执行的过程频繁使用了某些table对象,我们也可以把table常驻内存,以提高过程中sql的执行效率。
下面说说让执行部分常驻内存的方法,如何使用DBMS_SHARED_POOL将对象常驻内存。
写了大半,网上有哥们写的比俺还详细,以下这段copy吧。
1、DBMS_SHARED_POOL作用
DBMS_SHARED_POOL包的作用把需要的对象pin在shared pool中,由此被pin住的对象就
不再受shared pool LRU法则的约束而永久的驻留在shared pool中。
2、DBMS_SHARED_POOL与shared_pool_reserved区别
shared_pool_reserverd的含义是,当shared_pool 被不断的写入,同时由于LRU法则的存在
较旧的对象被交换出去,这样就会造成shared_pool被分割成许多较小的区域,这时如果应用
请求一个 较大的连续的内存区域时,如果没有shared_pool_reserved的存在,oracle就会
去搜索整个shared pool以寻找一个连续的较大区域,当搜索不到满足需求的区域时,oracle
就不得不释放一些区域来满足新来的需求,这样就可能造成性能的下降,因为被释放的区域可能
恰恰是其他应用所需要的,oracle又不得不进行重新解析。为了避免这种情况的出现,
shared_pool_reserverd_size用来设置一个shared pool 保留的区域,用于应用对较大内存
区域的需求,保留区的信息可以查询v$shared_pool_reserved视图。
3、创建DBMS_SHARED_POOL包
DBMS_SHARED_POOL可以由?\RDBMS\ADMIN\DBMSPOOL.SQL创建
SQL> @?\rdbms\admin\dbmspool.sql
程序包已创建。
授权成功。
视图已创建。
程序包体已创建。
查询v$db_object_cache视图,看dbms_job包在library cache中的状态。
v$db_object_cache用于查询cache在library cache中的对象信息,这里的对象包括表,
索引,聚簇,同义词,PL/SQL过程,包,触发器。
SQL> col name for a20
SQL> col type for a20
SQL> select name,type,sharable_mem,loads,kept from v$db_object_cache
2 where upper(name)=upper('dbms_job');
NAME
TYPE
SHARABLE_MEM LOADS KEP
-------------------- -------------------- ------------ ---------- ---
DBMS_JOB
NOT
LOADED
0 1 NO
DBMS_JOB
NOT
LOADED
0 1 NO
对dbms_job包进行keep操作
SQL> exec dbms_shared_pool.keep('dbms_job');
PL/SQL 过程已成功完成。
SQL> select name,type,sharable_mem,loads,kept from v$db_object_cache
2 where upper(name)=upper('dbms_job');
NAME
TYPE
SHARABLE_MEM LOADS KEP
-------------------- -------------------- ------------ ---------- ---
DBMS_JOB
PACKAGE
20828 2 YES
DBMS_JOB
PACKAGE
BODY
12636 2 YES
对dbms_job包进行unkeep操作
SQL> exec
dbms_shared_pool.unkeep('dbms_job');
PL/SQL 过程已成功完成。
SQL> select
name,type,sharable_mem,loads,kept from v$db_object_cache
2 where upper(name)=upper('dbms_job');
NAME
TYPE
SHARABLE_MEM LOADS KEP
-------------------- -------------------- ------------ ---------- ---
DBMS_JOB
PACKAGE
20828 2 NO
DBMS_JOB
PACKAGE
BODY
12636 2 NO
FLUSH
shared pool
SQL> alter system flush shared_pool;
系统已更改。
SQL> select
name,type,sharable_mem,loads,kept from v$db_object_cache
2 where upper(name)=upper('dbms_job');
NAME
TYPE
SHARABLE_MEM LOADS KEP
-------------------- -------------------- ------------ ---------- ---
DBMS_JOB
NOT
LOADED
0 2 NO
DBMS_JOB
NOT
LOADED
0 2 NO
三 NATIVE编译
偶在工作中也很少使用到,其实很多时候还是数据类型以及书写方法更重要,不过native编译还是有点用处的,不过oracle10g之后效果就不明显了,而在oracle11g中已经自动的给存储过程native编译了。
Native编译通过将 PL/SQL 模块(程序包、触发器、过程、函数和类型)编译成驻留在共享库中的纯代码来加速它们的运行。过程被转换成 C 代码,然后用一个 C 编译器进行编译,并与 Oracle 进程动态链接。
如果未使用native编译,则将每个 PL/SQL 程序单元编译成一种中间形式的机器可读码 (MCode)。MCode 存储在数据库字典中,并在运行时进行解释。
使用 PL/SQL native编译,将 PL/SQL 程序编译成无需运行时解释的纯机器码,从而加快运行速度。
Oracle10g native 设定方法
确保配置了以下条件:
1.确保spnc_commands($oracle_home/plsql/spnc_commands)具有正确的命令模板并且安装了恰当的C编译器;
设置了PLSQL_NATIVE_LIBRARY_DIR参数(创建存放编译记过的目录的绝对路径);
设置了PLSQL_NATIVE_LIBRARY_SUBDIR_COUNT;
可以编译单个PL/SQL单元;
2. 关闭应用程序服务,监听,数据库;
关闭所有应用程序服务,包括FORMS,WEB服务器等;
关闭TNS监听;
正常或者IMMEDIATE关闭数据库;
3. 在数据库初始化参数文件中设置PLSQL_CODE_TYPE为TRUE;
4. 使用UPGRADE选项启动数据库;
5. 执行以下过程列出所有INVALID的PL/SQL单元。
SELECT o.OWNER, o.OBJECT_NAME,
o.OBJECT_TYPE
FROM DBA_OBJECTS o, DBA_PLSQL_OBJECT_SETTINGS
s
WHERE o.OBJECT_NAME = s.NAME
AND o.STATUS = 'INVALID';
如果任何内置的对象无效,尝试使它们重新生效:
ALTER PACKAGE OLAPSYS.DBMS_AWM COMPILE BODY REUSE SETTINGS;
6.执行以下查询确定NATIVE和INTERPRETED的对象的数量
SELECT TYPE, PLSQL_CODE_TYPE, COUNT(*)
FROM DBA_PLSQL_OBJECT_SETTINGS
WHERE PLSQL_CODE_TYPE IS NOT NULL
GROUP BY TYPE, PLSQL_CODE_TYPE
ORDER BY TYPE, PLSQL_CODE_TYPE;
plsql_code_type为NULL的对象可以忽略。
7.以SYS运行$ORACLE_HOME/rdbms/admin/dbmsupgnv.sql更新DD中所有PL/SQL单元的plsql_code_type为NATIVE,然后使用TRUE排除包声明。该过程必须在数据库在UPGRADE模式时完成。
8.关闭并且NORMAL启动数据库,执行ALTER SYSTEM ENABLE RESTRICTED SESSION;
9.运行$ORACLE_HOME/rdbms/admin/utlrp.sql命令,该脚本重编译所有PL/SQL模块,如果非正常终止,则重新运行。
10.在编译完全成功后,确保没有新的无效PL/SQL,使用第五步的脚本;
11.运行第6步,确保除TYPE 和包声明外,全部PL/SQL单元为NATIVE,如果运行了dbmsupgin.sql,则全部为INTERPRETED。
12.执行ALTER SYSTEM DISABLE RESTRICTED SESSION;
Oracle11g native的设定方法
11g就简单多了 Oracle弄了个pl/sql编译器比c编译器还牛掰。
改两参数
alter system set plsql_code_type=native;
alter system set plsql_optimize_level=3;
PLSQL_OPTIMIZE_LEVEL 这个参数还是介绍下,oracle一般都建议我们不要修改
在10g中还没3这个值
等于0呢,没什么实际意义
1表示不做任何特殊处理
2可能会修改你的源码,做一些优化
设置为3时,PL/SQL 编译器重写代码以内联该代码。
针对单个的plsql程序
alter procedure 'XXX' compile plsql_code_type=native;
alter procedure 'XXX' compile plsql_optimize_level=3;
可以通过all_plsql_object_settings视图来查看plsql代码的编译方式
官方文档上说比C编译器快1-2倍,用了循环乘法测试,速度比解释方式快10倍,当然普通的程序不可能快这么多,反正总是好功能。来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/23754390/viewspace-697885/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/23754390/viewspace-697885/