Oracle 技术网

使用 Pro*C 开发基于 Oracle Database 11g 的 C 和 C++ 应用程序

<不要删除此文本,因为它是在浏览器中运行时生成的“主要”标题列表的占位符>

目的

在本教程中,您将在几个阶段中分析并执行 C 程序以了解 Pro*C 的特性和功能。

您将学习如何创建和使用报告(ADDM 报告 — Automatic Database Diagnostic Monitor,以及 AWR 报告 — Automatic Workload Repository)以对示例应用程序的性能和瓶颈问题进行分析。随着报告的运行,您分几个阶段来分析和优化示例程序。最终将产生一个高效的应用程序。

所需时间

大约 60 分钟。

前提条件

开始本教程之前,您应该:

1.

安装 Oracle Database 11g 第 2 版(如果尚未安装)

2.

安装 Pro*C 预编译器。

3.

下载 proclab.zip 文件并将其解压缩到您的工作目录(即 /home/oci/proclab)中。

概述

在本教程中,您将采用分步方式分几个阶段来运行和优化应用程序。从未经过优化的代码开始,每个阶段通过使用语句缓存、客户端结果集缓存等特性为这个未经优化的阶段添砖加瓦,最终使程序性能得以改善。几个阶段展示了 LOB 处理以及通过一个引用游标进行获取等特性。

AWR 报告和 ADDM 报告

Automatic Workload Repository (AWR) 是每个 Oracle Database 中内置的一个信息库。Oracle Database 定期生成所有重要统计信息和负载信息的快照并将这些快照存储在 AWR 中。

Automatic Database Diagnostic Monitor (ADDM) 能让 Oracle Database 对自身的性能进行诊断并确定可以解决所发现问题的方法。每次进行 AWR 统计捕获之后会都会自动运行该监视程序,从而使性能诊断数据随时可用。

要运行这些报告,可以使用本教程提供的 reports.sql 脚本。在您要查看的每个阶段中,由相应 pc 文件生成的可执行文件以及一些额外的参数将传递给该脚本 (reports.sql)。

使用 Pro*C 驱动程序开发 C 应用程序

Pro*C 概述

这里的 Pro*C 分析所使用的源代码文件名为 stage1.pc、stage2.pc、stage3.pc、stage4.pc、stage5.pc、stage6.pcstage7.pc,另外还有一个名为 helper.pc 的通用库文件,这里所有的阶段都将使用它。这些文件存放于 /home/oci/proclab 位置。

在本文中,您将查看一个 Pro*C 应用程序的 7 个阶段。其中一些阶段(stage3、stage4、stage5)旨在进行性能优化,而其他阶段(stage2、stage6、stage7)旨在说明特定的特性。通过对示例应用程序生成 ADDM 和 AWR 报告,您可以对性能和瓶颈问题进行分析。

示例 Pro*C 应用程序

prochol 模式中定义了以下对象:

MYEMP 表的定义为:

CREATE TABLE myemp (
 empno number(4) primary key,
 ename varchar2(10),
 job varchar2(9),
 mgr number(4),
 hiredate date,
 sal number(7,2),
 comm number(7,2),
 deptno number(2)) 
; 

为了演示 LOB 特性,定义了下表:

CREATE TABLE lob_table(
 article_no number(5),
 article_nm varchar2(50),
 article_text clob,
 comments clob)
 LOB(article_text) STORE AS SECUREFILE (TABLESPACE SYSAUX
                   COMPRESS low CACHE),
 LOB(comments) STORE AS SECUREFILE (TABLESPACE SYSAUX
                   COMPRESS low CACHE) 
;

在该 Pro*C 应用程序中使用了以下三个过程:

其主要的 C 函数为:

要对各个阶段的源代码进行编译和链接,可以使用 make 实用程序。

第 1 阶段:准备

本节不进行任何优化。main 线程执行以下初始化工作:

在初始化完成后,main 线程生成若干子线程(可通过 -t 选项配置生成的子线程的数量)。每个子线程开始时会调用函数 thread_function()。每个子线程执行以下操作:

  1. 分配自己的运行时上下文。
  2. 使用其运行时上下文创建自己的连接
  3. 以指定的次数调用负载函数 do_workload()(可通过 -i 选项配置调用次数)。该负载函数调用以下函数:

每个子线程完成其负载调用后,main 线程将这些子线程合并起来,计算并输出所有查询的性能统计信息以及该应用程序总共花费的时间。

.

打开一个终端窗口。

转到 /home/oci/proclab 目录,启动 SQL*Plus。以 system 用户身份登录。使用口令“manager”。

查看 stage1.pc 文件的内容。可使用一个文本编辑器来查看内容。

注意:如果当前的工作环境为 Linux,可能需要更改权限以便执行 stagen 文件。为此,在命令提示符处执行以下命令:


chmod 777 stage*
exit 

.

使用 gmake 实用程序生成 stage1 源代码的 C 可执行程序和库。打开一个终端窗口,转到(用“cd”命令)阶段文件所在位置 (/home/oci/proclab),执行 gmake 实用程序。

cd $HOME/oci/proclab
gmake stage1

 

.

reports.sql 脚本存放在 $HOME/oci/proclab/sql 目录中。在一个新的终端会话中,转到 $HOME/oci/proclab/sql 目录。

cd $HOME/oci/proclab/sql 

启动 SQL*Plus。在您的 SQL*Plus 会话中,运行 reports.sql 脚本。将 stage1 文件传递给该脚本。添加参数,指定迭代 10 次以增加负载并生成结果,将线程数设置为 30。

(注意:我们有意将迭代次数设置为 10 这么一个较低的值,目的是节省此练习的时间。而对于此阶段生成的固有的报告,迭代次数设置为 500。)

@reports.sql "../stage1 -i 10 -t 30"

报告运行时会显示完成百分比。

.

当提示输入报告名称时,请输入:
stage1_proc

这会生成两个报告,它们保存在当前目录中:

    • stage1_proc_addm.txt — ADDM 报告。
    • stage1_proc_awr.html — AWR 报告。

每个阶段都会为您提供生成的示例结果。这些文件位于 /home/oci/proclab/doc 子文件夹下。. 这些示例结果文件名为:

    • stage1_results_addm.txt — ADDM 报告。
    • stage1_results_awr.html — AWR 报告。

注意:由于环境不同,您的结果可能会与提供的示例结果不同。为了本教程内统一起见,我们查看的是生成的示例结果。

 

.

查看 stage1_results.txt 报告内容。

(您可以在一个文本编辑器中打开该文件,也可以在您的 SQL*Plus 会话中向上滚动查看该文件)

注意 Summary of Findings 部分。

 

.

查看 stage1_results_awr.htm 报告内容。

找到 stage1_results_awr.htm 文件。双击文件名,在浏览器中打开该文件(或右键单击并选择 Open with "Web-Browser" 选项)。

查看该报告。

向下滚动到 Main Report。单击 SQL Statistics 链接。

注意 Elapsed Time 统计信息。随着您经历每个阶段并采用不同的调优方法,这些数值将改变(将改善)。

第 2 阶段:使用数组 DML Fetch

本节将使用数组 fetch 来优化 C 代码,本节还将演示对可滚动游标的使用。在此阶段中,使用一个数组执行多行获取,该数组针对每次获取可保存 ARRAY_LENGTH 行。除了 multirow_fetch() 函数之外,此阶段的其余代码与 stage1 代码相同。

multirow_fetch() 函数通过一个以 FETCH_LOOP 计数的循环获取成倍的 ARRAY_LENGTH(定义于该函数自身中)个记录行。在该程序中,ARRAY_LENGTH 设置为 3,意味着该程序一次获取 3 行。在第一次循环中获取首个 3 行,在第二次循环中获取第二个 3 行,继续下去直到命中 FETCH_LOOP 计数。

我们通过绝对行号获取成倍的 ARRAY_LENGTH 个记录行。为了完整起见,我们在此演示中按顺序获取所有行。但一般情况下,通过可滚动游标可从结果集中任意特定行号开始获取任意数量的记录行。

.

查看 stage2.pc 文件的内容。

找到 /home/oci/proclab 目录下的 stage2.pc 文件。

右键单击 stage2.pc 文件,选择 Open with "Text Editor" 选项。

stage2.pc 中,将使用数组 DML fetch 和可滚动游标选项。

 

.

使用 gmake 实用程序生成 stage2 源代码的 C 可执行程序和库。打开一个终端窗口,转到(用“cd”命令)阶段文件所在位置 (/home/oci/proclab),执行 gmake 实用程序。

cd $HOME/oci/proclab
gmake stage2

 

.

在终端窗口中执行 stage2 文件。同时指定迭代参数 5,线程参数 5,指定 verbose 选项以输出详细信息。

./stage2 -i 5 -t 5 -v 

第 3 阶段:启用连接池

在本节中,您将启用连接池。为此,使用以下预编译时选项:

.

查看位于 cd $HOME/oci/proclab 目录下的 stage3.pc 文件的内容。 可使用一个文本编辑器来查看内容。


.

使用 gmake 实用程序生成 stage3 源代码的 C 可执行程序和库。打开一个终端窗口,转到(用“cd”命令)阶段文件所在位置 (/home/oci/proclab),执行 gmake 实用程序。

cd $HOME/oci/proclab
gmake stage3 

 

.

在您的 SQL*Plus 会话中,运行 reports.sql 脚本。将 stage3 文件传递给该脚本。添加参数,指定迭代 500 次以增加负载并生成结果,将线程数设置为 30。

@reports.sql "../stage3 -i 500 -t 30" 

报告运行时会显示完成百分比。

 

.

当提示输入报告名称时,请输入:

stage3_proc

这会生成两个报告,它们保存在当前目录中:

    • stage3_proc_addm.txt — ADDM 报告。
    • stage3_proc_awr.html — AWR 报告。

每个阶段都会为您提供生成的示例结果。这些文件位于 /home/oci/proclab/doc 子文件夹下。这些示例结果文件名为:

    • stage3_results_addm.txt — ADDM 报告。
    • stage3_results_awr.html — AWR 报告。

注意:由于环境不同,您的结果可能会与提供的示例结果不同。为了本教程内统一起见,我们查看的是生成的示例结果。

 

.

查看 stage3_results_addm.txt 报告内容。

(您可以在一个文本编辑器中打开该文件,也可以在您的 SQL*Plus 会话中向上滚动查看该文件)

注意 Summary of Findings 部分。

 

.

查看 stage3_results_awr.htm 报告内容。

找到 file stage3_results_awr.htm 文件。双击文件名,在浏览器中打开该文件(或右键单击并选择 Open with "Web-Browser" 选项)。

查看该报告。

向下滚动到 Main Report。单击 SQL Statistics 链接。

注意,与 stage1 相比,这里的 Elapsed Time(s) 明显减少。

第 4 阶段:使用语句缓存特性

在本节中,您将使用语句缓存特性。此阶段将启用语句缓存特性,除此之外与第 1 阶段相同。这可通过使用以下预编译器选项进行预编译来实现:

.

查看位于 /home/oci/proclab 目录下的 stage4.pc 文件的内容。 可使用一个文本编辑器来查看内容。


.

使用 gmake 实用程序生成 stage4 源代码的 C 可执行程序和库。打开一个终端窗口,转到(用“cd”命令)阶段文件所在位置 (/home/oci/proclab),执行 gmake 实用程序。

cd $HOME/oci/proclab
gmake stage4

 

.

在您的 SQL*Plus 会话中,运行 reports.sql 脚本。将 stage4 文件传递给该脚本。添加参数,指定迭代 500 次以增加负载并生成结果,将线程数设置为 30。

@reports.sql "../stage4 -i 500 -t 30"

报告运行时会显示完成百分比。

 

.

当提示输入报告名称时,请输入:

stage4_proc 

这会生成两个报告,它们保存在当前目录中:

    • stage4_proc_addm.txt — ADDM 报告。
    • stage4_proc_awr.html — AWR 报告。

每个阶段都会为您提供生成的示例结果。这些文件位于 /home/oci/proclab/doc 子文件夹下。这些示例结果文件名为:

    • stage4_results_addm.txt — ADDM 报告。
    • stage4_results_awr.html — AWR 报告。

注意:由于环境不同,您的结果可能会与提供的示例结果不同。为了本教程内统一起见,我们查看的是生成的示例结果。

 

.

查看 stage4_results_addm.txt 报告内容。

(您可以在一个文本编辑器中打开该文件,也可以在您的 SQL*Plus 会话中向上滚动查看该文件)

注意 Summary of Findings 部分。

 

.

查看 stage4_results_awr.htm 报告内容。

找到 stage4_results_awr.htm 文件。双击文件名,在浏览器中打开该文件(或右键单击并选择 Open with "Web-Browser" 选项)。

查看该报告。

向下滚动到 Main Report。单击 SQL Statistics 链接。

注意 Stage1 和 Stage4 之间在解析调用次数方面的差异。

  • Stage1:总的解析调用个数:197,221。解析计数 = UPDATESELECT 语句的执行计数。
  • Stage4:总的解析调用个数:165,634。最后一个 select 的解析计数为 30,但却有 15,000 次执行。

第 5 阶段:使用客户端结果集缓存特性

在本节中,您将启用结果集缓存特性,然后查看其结果。此阶段将启用客户端结果集缓存特性,除此之外与第 1 阶段相同。为此,我们将对 SELECT 语句添加 SQL 提示。在本节中,我们将只修改 SELECT 语句,其余代码保持不变,仍与 stage1 相同。在此阶段最后将显示客户端结果缓存统计信息。

.

您将需要启用客户端结果集缓存特性。

init.ora 文件中设置了以下语句:

client_result_cache_size=65536 
client_result_cache_lag=1000000 
compatible=11.0.00.0

如果该项设置不存在,您需要:

  1. 以 sysdba 身份登录到数据库
  2. 在 SQL*Plus 中,通过执行以下命令关闭该数据库:shutdown immediate
  3. init.ora 文件中添加该项设置,然后保存该文件。
  4. 在 SQL*Plus 中,通过执行以下命令启动该数据库:startup open

 

.

查看 stage5.pc 文件的内容。可使用一个文本编辑器来查看内容。

 

.

使用 gmake 实用程序生成 stage5 源代码的 C 可执行程序和库。打开一个终端窗口,转到(用“cd”命令)阶段文件所在位置 (/home/oci/proclab),执行 gmake 实用程序。

cd $HOME/oci/proclab
gmake stage5

 

.

在您的 SQL*Plus 会话中,运行 reports.sql 脚本。将 stage5 文件传递给该脚本。添加参数,指定迭代 500 次以增加负载并生成结果,将线程数设置为 30。

@reports.sql "../stage5 -i 500 -t 30" 

报告运行时会显示完成百分比。

 

.

当提示输入报告名称时,请输入:

stage5_proc

这会生成两个报告,它们保存在当前目录中:

    • stage5_proc_addm.txt — ADDM 报告。
    • stage5_proc_awr.html — AWR 报告。

每个阶段都会为您提供生成的示例结果。这些文件位于 /home/oci/proclab/doc 子文件夹下。这些示例结果文件名为:

    • stage5_results_addm.txt — ADDM 报告。
    • stage5_results_awr.html — AWR 报告。

注意:由于环境不同,您的结果可能会与提供的示例结果不同。为了本教程内统一起见,我们查看的是生成的示例结果。

 

.

查看 stage5_results_addm.txt 报告内容。

(您可以在一个文本编辑器中打开该文件,也可以在您的 SQL*Plus 会话中向上滚动查看该文件)

注意 Summary of Findings 部分。

 

.

查看 stage5_results_awr.htm 报告内容。

找到 stage5_results_awr.htm 文件。双击文件名,在浏览器中打开该文件(或右键单击并选择 Open with "Web-Browser" 选项)。

查看该报告。

向下滚动到 Main Report。单击 SQL Statistics 链接。

查看该报告。单击 SQL ordered by Executions 链接。

  1. 在此阶段中,我们已对多行查询添加了一个查询级提示。
  2. 单行查询保留为非注释。
  3. 客户端执行两个查询约 15,000 次。
  4. 您会看到多行查询的执行次数明显变少。这是因为我们使用了客户端查询缓存,不用访问服务器,从本地即可确定结果。

第 6 阶段:调用 PL/SQL 过程

在本节中,我们将修改 multirow_fetch() 函数,使其调用在 createtables.sql 脚本中定义的一个 PL/SQL 存储过程。(您可以获得该脚本,在准备这一课程时已执行了该脚本)。multirow_fetch() 函数用 sql_cursor pseudotype 声明一个引用游标,分配这个引用游标,然后调用一个 PL/SQL 存储过程来填充该引用游标所指空间。一旦由 PL/SQL 存储过程返回,该引用游标的行为就类似于 Pro*C 应用程序中静态声明的游标。multirow_fetch() 函数:

.

查看 stage6.pc 文件的内容。

找到 /home/oci/proclab 目录下的 stage6.pc 文件。

右键单击 stage6.pc 文件,选择 Open with "Text Editor" 选项。

stage6.pc 中,合并了各个线程,计算并输出所有查询的性能统计信息。

 

.

使用 gmake 实用程序生成 stage6 源代码的 C 可执行程序和库。打开一个终端窗口,转到(用“cd”命令)阶段文件所在位置 (/home/oci/proclab),执行 gmake 实用程序。

gmake cd $HOME/oci/proclab
stage6

 

.

在终端窗口中执行 stage6 文件。同时指定迭代参数 5,线程参数 5,指定 verbose 选项以输出详细信息。

./stage6 -i 5 -t 5 -v 

 

第 7 阶段:LOB 处理

在本节中,您将看到在 Pro*C 中对 LOB 的处理。此阶段将修改 multirow_fetch() 函数,使该函数检索针对此教程而创建的 lob_table 表中的 LOB 数据并更新其 LOB 列。这里既没有调用 query_salary() 函数也没有调用 update_salary() 函数,因为此阶段只使用 lob_table

为了演示如何处理 LOB,修改了以下两个函数: >

.

查看 stage7.pc 文件的内容。

找到 /home/oci/proclab 目录下的 stage7.pc 文件。

右键单击 stage7.pc 文件,选择 Open with "Text Editor" 选项。

stage7.pc 中演示了对 LOB 的处理。

 

.

使用 gmake 实用程序生成 stage7 源代码的 C 可执行程序和库。打开一个终端窗口,转到(用“cd”命令)阶段文件所在位置 (/home/oci/proclab),执行 gmake 实用程序。

cd $HOME/oci/proclab
gmake stage7

 

.

在终端窗口中执行 stage7 文件。同时指定迭代参数 10,线程参数 5,指定 verbose 选项以输出详细信息。

./stage7 -i 10 -t 5 -v 

.

在一个 SQL*Plus 会话中查看 lob_table 的内容:

DESCRIBE lob_table 

select count(*) from  lob_table; 

从 lob_table 中检索 article_text 和 comments。

执行以下 SQL*Plus 命令对输出结果进行格式化。

set linesize 120
column article_text forma a40
column comments format a40

执行以下 SELECT 语句:

select article_text, comments 
from lob_table;

总结

在本教程中,您学习了如何:

Oracle Is The Information Company 关于 Oracle | Oracle RSS 信源 | 招聘 | 联系我们 | 网站地图 | 法律声明 | 使用条款 | 您的隐私权利