百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

Oracle 11g中的Native PL/SQL代码编译

mhr18 2024-10-12 04:23 18 浏览 0 评论

Oracle环境中,PL/SQL是我们进行业务逻辑实现的最佳手段,同时也是和Oracle数据库本身结合的最好的语言。使用好PL/SQL本身功能,可以大幅度提高我们的工作效率。

我们从最开始学习计算机和编程开始,就接触到一个概念叫做“二进制程序码”。计算机可以直接进行二进制代码的执行,就目前而言,二进制是计算机执行速度最快的一种形式。其他的高级语言,如C、C++,都是通过编译Compile和连接Link过程,转化为二进制程序。

二进制程序的特点是执行速度快。但是缺点也是明显的,那就是针对一种物理机器类型(如CPU架构)、一种操作系统,二进制执行程序的格式定义都是不同的。所以,针对每一种操作系统和物理平台,理论上我们都需要进行一遍Compile和Link过程,形成独特的可执行程序。

中立语言,或者称为中间语言的出现,结束了这样的局面。这种代表性就是Java和诸多的脚本语言,借助一个“平台相关”的虚拟机软件,我们可以让相同的代码在不同平台上运行。这也就是所谓的“一次编译,多处执行”。

默认情况下,PL/SQL代码就是这样的中间语言,也可以称为解释语言。在不同的平台上,相同的代码在运行。相对于Native代码而言,解析代码的性能一直是人们关注的重要问题。将代码Native本地化,是人们经常提到的一种程序优化手段。

1、PL/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 Release 11.2.0.3.0 - Production

PL/SQL Release 11.2.0.3.0 - Production

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> alter procedure p_rece_call_test compile plsql_code_type=native;

Procedure altered

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> alter session set plsql_code_type='native';

Session altered

SQL> alter procedure p_rece_call_test compile;

Procedure altered

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 Release 11.2.0.3.0

Connected as scott

SQL> alter procedure p_rece_call_test compile;

Procedure altered

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<=2) then

6 return n;

7 else

8 return fib(n-1)+fib(n-2);

9 end if;

10 end;

11 /

Function created

SQL> select name, plsql_code_type from user_plsql_object_settings;

NAME PLSQL_CODE_TYPE

------------------------------ --------------------

FIB INTERPRETED

执行实验前,清理shared_pool和buffer_cache。

SQL> alter system flush shared_pool;

System altered.

SQL> alter system flush buffer_cache;

System altered.

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> alter function fib compile plsql_code_type=native;

Function altered

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> alter system flush shared_pool;

System altered.

SQL> alter system flush buffer_cache;

System altered.

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化的程序在迁移、升级的时候,也许会有很多额外的问题和关注点。也是我们需要注意慎用的方面。

相关推荐

【推荐】一个开源免费、AI 驱动的智能数据管理系统,支持多数据库

如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!.前言在当今数据驱动的时代,高效、智能地管理数据已成为企业和个人不可或缺的能力。为了满足这一需求,我们推出了这款开...

Pure Storage推出统一数据管理云平台及新闪存阵列

PureStorage公司今日推出企业数据云(EnterpriseDataCloud),称其为组织在混合环境中存储、管理和使用数据方式的全面架构升级。该公司表示,EDC使组织能够在本地、云端和混...

对Java学习的10条建议(对java课程的建议)

不少Java的初学者一开始都是信心满满准备迎接挑战,但是经过一段时间的学习之后,多少都会碰到各种挫败,以下北风网就总结一些对于初学者非常有用的建议,希望能够给他们解决现实中的问题。Java编程的准备:...

SQLShift 重大更新:Oracle→PostgreSQL 存储过程转换功能上线!

官网:https://sqlshift.cn/6月,SQLShift迎来重大版本更新!作为国内首个支持Oracle->OceanBase存储过程智能转换的工具,SQLShift在过去一...

JDK21有没有什么稳定、简单又强势的特性?

佳未阿里云开发者2025年03月05日08:30浙江阿里妹导读这篇文章主要介绍了Java虚拟线程的发展及其在AJDK中的实现和优化。阅前声明:本文介绍的内容基于AJDK21.0.5[1]以及以上...

「松勤软件测试」网站总出现404 bug?总结8个原因,不信解决不了

在进行网站测试的时候,有没有碰到过网站崩溃,打不开,出现404错误等各种现象,如果你碰到了,那么恭喜你,你的网站出问题了,是什么原因导致网站出问题呢,根据松勤软件测试的总结如下:01数据库中的表空间不...

Java面试题及答案最全总结(2025版)

大家好,我是Java面试陪考员最近很多小伙伴在忙着找工作,给大家整理了一份非常全面的Java面试题及答案。涉及的内容非常全面,包含:Spring、MySQL、JVM、Redis、Linux、Sprin...

数据库日常运维工作内容(数据库日常运维 工作内容)

#数据库日常运维工作包括哪些内容?#数据库日常运维工作是一个涵盖多个层面的综合性任务,以下是详细的分类和内容说明:一、数据库运维核心工作监控与告警性能监控:实时监控CPU、内存、I/O、连接数、锁等待...

分布式之系统底层原理(上)(底层分布式技术)

作者:allanpan,腾讯IEG高级后台工程师导言分布式事务是分布式系统必不可少的组成部分,基本上只要实现一个分布式系统就逃不开对分布式事务的支持。本文从分布式事务这个概念切入,尝试对分布式事务...

oracle 死锁了怎么办?kill 进程 直接上干货

1、查看死锁是否存在selectusername,lockwait,status,machine,programfromv$sessionwheresidin(selectsession...

SpringBoot 各种分页查询方式详解(全网最全)

一、分页查询基础概念与原理1.1什么是分页查询分页查询是指将大量数据分割成多个小块(页)进行展示的技术,它是现代Web应用中必不可少的功能。想象一下你去图书馆找书,如果所有书都堆在一张桌子上,你很难...

《战场兄弟》全事件攻略 一般事件合同事件红装及隐藏职业攻略

《战场兄弟》全事件攻略,一般事件合同事件红装及隐藏职业攻略。《战场兄弟》事件奖励,事件条件。《战场兄弟》是OverhypeStudios制作发行的一款由xcom和桌游为灵感来源,以中世纪、低魔奇幻为...

LoadRunner(loadrunner录制不到脚本)

一、核心组件与工作流程LoadRunner性能测试工具-并发测试-正版软件下载-使用教程-价格-官方代理商的架构围绕三大核心组件构建,形成完整测试闭环:VirtualUserGenerator(...

Redis数据类型介绍(redis 数据类型)

介绍Redis支持五种数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)及Zset(sortedset:有序集合)。1、字符串类型概述1.1、数据类型Redis支持...

RMAN备份监控及优化总结(rman备份原理)

今天主要介绍一下如何对RMAN备份监控及优化,这里就不讲rman备份的一些原理了,仅供参考。一、监控RMAN备份1、确定备份源与备份设备的最大速度从磁盘读的速度和磁带写的带度、备份的速度不可能超出这两...

取消回复欢迎 发表评论: