设为首页 收藏本站
查看: 2014|回复: 0

[经验分享] Oracle 11g中PL/SQL代码编译类型Native/INTERPRETED 讲解

[复制链接]

尚未签到

发表于 2018-10-19 09:34:38 | 显示全部楼层 |阅读模式
  Oracle环境中,PL/SQL是我们进行业务逻辑实现的最佳手段,同时也是和Oracle数据库本身结合的最好的语言。使用好PL/SQL本身功能,可以大幅度提高我们的工作效率。
  我们从最开始学习计算机和编程开始,就接触到一个概念叫做“二进制程序码”。计算机可以直接进行二进制代码的执行,就目前而言,二进制是计算机执行速度最快的一种形式。其他的高级语言,如C、C++,都是通过编译Compile和连接Link过程,转化为二进制程序。
  二进制程序的特点是执行速度快。但是缺点也是明显的,那就是针对一种物理机器类型(如CPU架构)、一种操作系统,二进制执行程序的格式定义都是不同的。所以,针对每一种操作系统和物理平台,理论上我们都需要进行一遍Compile和Link过程,形成独特的可执行程序。
  中立语言,或者称为中间语言的出现,结束了这样的局面。这种代表性就是Java和诸多的脚本语言,借助一个“平台相关”的虚拟机软件,我们可以让相同的代码在不同平台上运行。这也就是所谓的“一次编译,多处执行”。
  默认情况下,PL/SQL代码就是这样的中间语言,也可以称为解释语言。在不同的平台上,相同的代码在运行。相对于Native代码而言,解析代码的性能一直是人们关注的重要问题。将代码Native本地化,是人们经常提到的一种程序优化手段。
  1PL/SQL语句Native
  PL/SQL语句的Native化,是从Oracle9i引入的。最开始进行native的初衷就是性能,通常native的PL/SQL代码要比解释形式(interpreted form)执行速度快。早期的native化是比较费力气的,需要我们提供出本地的编译器地址。
  PL/SQL语句的native过程需要我们安装额外的C编译器,这个在一些生产环境下,还是有安全方面的顾虑的。
  在9i和10g时代,数据库中包括一个参数名为plsql_native_library_dir,用于指定本地的编译器目录位置。在11g中,这个参数被取消,进行代码native的过程也变得比较简单起来。
  在11g中,Oracle是不需要服务器上额外安装C编译器的。Oracle会直接将需要native化的PL/SQL代码转化到服务器上的shared library(DDL)。由此,进行PL/SQL的本地编译就变得很简单,只需要一个开关设备。这个就是Oracle参数plsql_code_type。
  在使用native PL/SQL的时候,我们一定注意使用内存对象的不同。Native PL/SQL代码对应的机器码(machine code)在被调入数据库catalog之前,是与PGA内存进行映射。而解释代码(interpreted form code)则是和SGA进行对应。所以,在使用native code的时候,对SGA的消耗是减少的趋势。
  2、开关参数plsql_code_type
  从Oracle 11g开始,我们可以使用plsql_code_type来控制编译器选择开关。我们选择Oracle11g进行实验。
  SQL> select * from v$version;
  BANNER
  --------------------------------------------------------------------------------

  Oracle Database 11g Enterprise Edition>
  PL/SQL>  CORE        11.2.0.3.0         Production
  TNS for Linux: Version 11.2.0.3.0 - Production
  NLSRTL Version 11.2.0.3.0 – Production
  相关参数
  SQL> show parameter plsql_code
  NAME                                 TYPE        VALUE
  ------------------------------------ ----------- ------------------------------
  plsql_code_type                      string      INTERPRETED
  默认情况下,Oracle是选择解释代码的形式进行编译的。通过视图user/all/dba_plsql_object_settings,我们是可以看到对应存储代码对象使用的编译形式的。
  首先,我们使用默认方式进行存储过程编译。
  SQL> create or replace procedure P_RECE_CALL_TEST is
  2  i number;
  3  c number;
  4  begin
  5    for i in 1..100 loop
  6        select count(*) into c from emp;
  7        dbms_output.put_line(to_char(c));
  8    end loop;
  9  end P_RECE_CALL_TEST;
  10  /
  Procedure created
  SQL> select name, plsql_code_type from user_plsql_object_settings;
  NAME                           PLSQL_CODE_TYPE
  ------------------------------ --------------------
  P_RECE_CALL_TEST               INTERPRETED
  代码对象的plsql_code_type列显示了对象的编译形式。我们对于单独的存储过程,可以不通过参数修改,而是在compile过程中,直接指定编译方式。这样也是可以将代码编译为native方式。

  SQL>>
  Procedure>  SQL> select name, plsql_code_type from user_plsql_object_settings;
  NAME                           PLSQL_CODE_TYPE
  ------------------------------ --------------------
  P_RECE_CALL_TEST               NATIVE
  配置参数plsql_code_type比较简单,目前版本Oracle支持Interpreted和Native两个选项值。默认取值为Interpreted,表示将程序代码编译为解析形式。另一个就是Native,表示编译为本地代码。我们可以在session level进行灵活的配置。

  SQL>>
  Session>
  SQL>>
  Procedure>  SQL>  select name, plsql_code_type from user_plsql_object_settings;
  NAME                           PLSQL_CODE_TYPE
  ------------------------------ --------------------
  P_RECE_CALL_TEST               NATIVE
  重新登录之后,可以将其编译回解释状态。
  SQL> conn scott/tiger@ora11g;

  Connected to Oracle Database 11g Enterprise Edition>  Connected as scott

  SQL>>
  Procedure>  SQL>  select name, plsql_code_type from user_plsql_object_settings;
  NAME                           PLSQL_CODE_TYPE
  ------------------------------ --------------------
  P_RECE_CALL_TEST               INTERPRETED
  3、性能对比
  PL/SQL本地化代码最大的好处和优势就在于性能。特别是11g版本下,本地Native的优势更加明显。
  我们选择一个比较消耗资源的函数——斐波纳妾数列计算第n项,采用递归的结构进行计算。
  SQL> create or replace function fib(n number)
  2  return number
  3  is
  4  begin
  5    if (n select name, plsql_code_type from user_plsql_object_settings;
  NAME                           PLSQL_CODE_TYPE
  ------------------------------ --------------------
  FIB                            INTERPRETED
  执行实验前,清理shared_pool和buffer_cache。

  SQL>>
  System>
  SQL>>
  System>  SQL> set timing on;
  SQL> set serveroutput on;
  SQL> declare
  2    n number;
  3  begin
  4    n := fib(40);
  5    dbms_output.put_line('Result is : '||n);
  6  end;
  7  /
  Result is : 165580141
  PL/SQL procedure successfully completed
  Executed in 43.547 seconds
  N=40时候,PL/SQL解释形式代码执行时间43.55s计算出结果。下面我们看看Native化之后的情况。

  SQL>>
  Function>  Executed in 0.219 seconds
  SQL> select name, plsql_code_type from user_plsql_object_settings;
  NAME                           PLSQL_CODE_TYPE
  ------------------------------ --------------------
  FIB                            NATIVE
  Executed in 0.078 seconds
  第二次执行相同计算任务。

  SQL>>
  System>
  SQL>>
  System>  SQL> set timing on;
  SQL> set serveroutput on;
  SQL> declare
  2    n number;
  3  begin
  4    n := fib(40);
  5    dbms_output.put_line('Result is : '||n);
  6  end;
  7  /
  Result is : 165580141
  PL/SQL procedure successfully completed
  Executed in 25.734 seconds
  第二次native执行情况,看出为25.73s完成计算。性能提升接近一半!
  4、结论
  我们在编写pl/sql代码的时候,性能是一个非常重要的考量方式。Native程序化在一定程度上可以提高效率。不过应该看到,Native化程序是有条件的。Native PL/SQL节省的时间成本在PL/SQL引擎的层面,而SQL语句引擎方面不会有很大程度的提升。
  所以,如果我们的代码中以流程、计算和循环判断为主体,SQL语句相对较少,那么使用Native化是比较“划算”的。反之,如果主要都是在进行SQL语句计算操作,即使我们将代码Native化,获取到的优势也比较少。
  另一方面,Native化的程序在迁移、升级的时候,也许会有很多额外的问题和关注点。也是我们需要注意慎用的方面。


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-623452-1-1.html 上篇帖子: Set nfs server on rhel7-11517071 下篇帖子: SQL Server数据库mdf文件中了勒索病毒****.mdf.work。扩展名变为work-jogewang123的博客
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表