Develop C and C++ Applications with Oracle Database 11g Using OCI

<Do not delete this text because it is a placeholder for the generated list of "main" topics when run in a browser>

Purpose

In this tutorial, you analyze and execute C programs in several stages to learn about the features and functionality of OCI.

You learn how to create and use reports (ADDM reports - Automatic Database Diagnostic Monitor and AWR reports - Automatic Workload Repository) to analyze the performance and bottleneck of a sample application. As the reports are run, you analyze and refine the sample in several stages. The end result is an efficient application.

Time to Complete

Approximately 60 minutes.

Prerequisites

Before you perform this tutorial, you should:

1.

Install Oracle Database 11g Release 2 (if not already present)

2.

Install the ODBC driver.

3.

Download and unzip the ocilab.zip file into your working directory (i.e./home/oci/ocilab )

Overview

In this tutorial you use a step by step approach to run and tune the application in several stages. Starting with non-optimized code, each stage adds up to this non-optimized stage showing the performance improvement by using features like statement caching, client side result set caching, etc. A few stages show specific features like LOB handling, and fetching through a ref-cursor.

The AWR and ADDM Reports

Automatic Workload Repository (AWR) is a built-in repository in every Oracle Database. At regular intervals, the Oracle Database makes a snapshot of all its important statistics and workload information and stores in AWR.

The Automatic Database Diagnostic Monitor (ADDM) enables the Oracle Database to diagnose its own performance and determine how identified problems could be resolved. It runs automatically after each AWR statistics capture, making the performance diagnostic data readily available.

To run the reports, you can use the reports.sql script provided with this tutorial. For each of the stages that you want to examine, the executable generated from corresponding C file is provided to the script (reports.sql) with a few additional parameters.

Developing C Application with the OCI Drivers

OCI Overview

For OCI analysis, the C source code files are name as stage1.c stage2.c stage3.c stage4.c stage5.c, stage6.c, and stage7.c with a common library file named helper.c that is used for all of the stages shown. These files are stored in the /home/oci/ocilab location.

In this section, you examine 7 stages of an OCI application. Stages 2, 3, 4, 5 illustrate performance related OCI features, while stage6 and stage7 illustrate PLSQL and (secure) Lob support in OCI. By generating the ADDM and AWR reports on the sample applications, you can analyze performance and bottlenecks. These reports are done for stages 1,2,3,4, and 5.

Each stage builds on the code changes done in previous stage. To see the code changes, you use the tkdiff utility to view a stage compared with the previous stage.

The Sample Application

The sample application uses the ocihol/welcome schema. It generates random numbers to simulate web inputs to update and query the MYEMP table.

The following objects are defined within the ocihol schema:

The MYEMP table is defined as:

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))
; 
To demonstrate client result caching, besides above table, following objects are used:
CREATE TABLE regions (
 region_id NUMBER CONSTRAINT region_id_nn NOT NULL,
 region_name varchar2(25)) ; 
CREATE OR REPLACE VIEW empview as
 select * from myemp
;

To demonstrate the LOB features, the following table is defined:

CREATE TABLE lob_table (
 lobid number primary key,
 lobcol clob) LOB(lobcol) 
  STORE AS SECUREFILE (TABLESPACE SYSAUX COMPRESS low CACHE)
;

The following three procedures are used in the OCI application:

The main C functions are:

To compile and link all of the stages of the source code, you can use the make utility.

Stage 1: Setting Up

In this section, no optimizations are performed. The main thread spawns the requested number of threads with a thread function (thread_function()) as an initial routine that each thread should be started with. The 'main' thread, spawns new threads.

Each thread does the following:

.

Open a terminal window.

Change to your /home/oci/ocilab directory and start SQL*Plus. Logon as system. Use the password "manager".

Examine the contents for the stage1.c file. You can use a text editor to view the contents.

Note: If you are working in a Linux environment, you may need to change the permission to execute the stagen files. To do so, execute the following at the command prompt:


chmod 777 stage*
exit 

.

Use the gmake utility to build the executable C programs and library for the source code for stage1. Start a terminal window, navigate (by using the 'cd' command) to the location where the stage files are (/home/oci/ocilab) and execute the gmake utility

cd $HOME/oci/ocilab
gmake stage1 

 

.

The reports.sql script is stored in the $HOME/oci/ocilab/sql directory. In a new terminal session, change to the $HOME/oci/ocilab/sql directory.

cd $HOME/oci/ocilab/sql 

Start SQL*Plus. In your SQL*Plus session, run the reports.sql script. Pass to it the stage1 file. Add the parameter to iterate 10 times to increase the workload and generate findings.

(Note: we have purposefully set the number of iterations to a low value of 10 to save time in this exercise. For the pre-canned reports generated for this stage, the number of iterations was set to 500.)

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

As the report runs, you are shown the percentage completed.

.

When prompted for the report name, enter:
stage1_oci 

This generates two reports which are saved in the current directory:

    • stage1_oci_addm.txt - the ADDM report.
    • stage1_oci_awr.html - the AWR report.

Generated sample results are provided to you for each stage. These files are located in the /home/oci/ocilab/doc sub-folder.. The names of the sample results files are:

    • stage1_results_addm.txt - the ADDM report.
    • stage1_results_awr.html - the AWR report.

Note: Your results may differ from the sample results provided due to environment differences. For consistency in this tutorial, the generated sample results are examined.

 

.

Examine the contents in the stage1_results.txt report.

(You can either open the file in a text editor, or you can scroll up in your SQL*Plus session.)

Note the summary of findings.

 

.

Examine the contents in the stage1_results_awr.htm report.

Find the file stage1_results_awr.htm. Double-click the file name to open the file in a browser (or right-click and select the Open with "Web-Browser" option).

Review the report .

Scroll down to the Main Report. Click the SQL Statistics link.

Note the Elapsed time statistics and number of SQL executions. As you go through each of the stages and apply different tuning methods, these numbers will change (and improve).

 

Stage 2: Using Array Fetch and Array DML

In this section, the C code is optimized for array fetch and array DML. The multi-row fetch is performed using an array, which can hold an ARRAY_SIZE number of rows for each fetch.

Note: The example uses regular forward scrolling cursor. OCI also supports readonly scrollable cursor that allows fetches in any direction (backward, forward) with random access. The result set is based on snapshot at query execution time. You have to set a special mode in OCIStmtExecute() to mark the query result-set as scrollable. Then use OCIStmtFetch2() to scroll the results. See OCI documentation for details.

.

Examine the contents for the stage2.c file and compare it to stage1.c . You can use the tkdiff utility to view the differences.

Execute the following command to view the stage2.c and stage1.c files.

tkdiff stage1.c stage2.c 

Note the differences in the files. In stage2.c array DML and array fetch is used.

I

 

.

Use the gmake utility to build the executable C programs and library for the source code for stage2. Start a terminal window, navigate (by using the 'cd' command) to the location where the stage files are (/home/oci/ocilab) and execute the gmake utility.

cd $HOME/oci/ocilab
gmake stage2

 

.

In your SQL*Plus session, run the reports.sql script. Pass to it the stage2 file. Add the parameter to iterate 500 times to increase the workload and generate findings.

@reports.sql "../stage2 -i 500"

As the report runs, you are shown the percentage completed.

.

When prompted for the report name, enter:
stage2_oci

This generates two reports which are saved in the current directory:

    • stage2_oci_addm.txt - the ADDM report.
    • stage2_oci_awr.html - the AWR report.

Generated sample results are provided to you for each stage. These files are located in the /home/oci/ocilab/doc sub-folder.. The names of the sample results files are:

    • stage2_results_addm.txt - the ADDM report.
    • stage2_results_awr.html - the AWR report.

Note: Your results may differ from the sample results provided due to environment differences. For consistency in this tutorial, the generated sample results are examined.

 

.

Examine the contents in the stage2_results.txt report.

(You can either open the file in a text editor, or you can scroll up in your SQL*Plus session.)

Note the summary of findings.

Note that Finding 2 recommends to use mid-tier connection pooling. This optimization is done in stage 3.

 

.

Examine the contents in the stage2_results_awr.htm report.

Find the file stage2_results_awr.htm. Double-click the file name to open the file in a browser (or right-click and select the Open with "Web-Browser" option).

Review the report.

Scroll down to the Main Report. Click the SQL Statistics link.

Note the Elapsed time statistics and number of SQL executions. As you go through each of the stages and apply different tuning methods, these numbers will change (and improve).

 

Stage 3: OCI Client-Side Session Pooling

This stage is same as stage2, but with OCI session pooling enabled. This is achieved by using the following configurations options set dynamically using the OCISessionPooling APIs in new method create_session_pool().

In the thread_function(), when each thread get a session per iteration, it comes from the pool instead of creating and destroying sessions (and hence connections) per iteration per thread.

Notes:


.

Examine the contents for the stage3.c file and compare it to stage2.c. You can use the tkdiff utility to view the differences.

Execute the following command to view the stage3.c and stage2.c files.

tkdiff stage2.c stage3.c 

Note the differences in the files. In stage3.c OCI session pooling is used.

Note: If you are working in a Linux environment, you may need to change the permission to execute the stagen files. To do so, execute the following at the command prompt:


chmod 777 stage*
exit 

.

Use the gmake utility to build the executable C programs and library for the source code for stage3. Start a terminal window, navigate (by using the 'cd' command) to the location where the stage files are (/home/oci/ocilab) and execute the gmake utility

cd $HOME/oci/ocilab
gmake stage3

 

.

In your SQL*Plus session, run the reports.sql script. Pass to it the stage3 file. Add the parameter to iterate 1000 times to increase the workload and generate findings.

@reports.sql "../stage3 -i 1000

As the report runs, you are shown the percentage completed.

.

When prompted for the report name, enter:
stage3_oci

This generates two reports which are saved in the current directory:

    • stage3_oci_addm.txt - the ADDM report.
    • stage3_oci_awr.html - the AWR report.

Generated sample results are provided to you for each stage. These files are located in the /home/oci/ocilab/doc sub-folder.. The names of the sample results files are:

    • stage3_results_addm.txt - the ADDM report.
    • stage3_results_awr.html - the AWR report.

Note: Your results may differ from the sample results provided due to environment differences. For consistency in this tutorial, the generated sample results are examined.

 

.

Examine the contents in the stage3_results.txt report.

(You can either open the file in a text editor, or you can scroll up in your SQL*Plus session.)

Note the summary of findings.

In the stage 2, Finding 2 was "Session Connect and Disconnect" - a recommendation to reduce the connects and disconnects. In stage 3, you do not see the recommendation to reduce connects and disconnects (i.e. connection pooling) now.

 

.

Examine the contents in the stage3_results_awr.htm report.

Find the file stage3_results_awr.htm. Double-click the file name to open the file in a browser (or right-click and select the Open with "Web-Browser" option).

Review the report .

Scroll down to the Main Report. Click the SQL Statistics link.

Note the Elapsed time statistics. As you go through each of the stages and apply different tuning methods, these numbers will change (and improve).

 

Stage 4: OCI with Client-Side Statement Caching Enabled

This stage is same as stage3, but with client-side statement caching enabled. This is achieved by setting statement cache size on the OCI Session Pool and indicating using this feature in the OCISessionPoolCreate() call.

When the call to OCIStmtPrepare2() is done, it checks to see if that SQL text exists in the client cache. There is one cache per client session. If no match is found, it goes to server to make a (soft) parse call and caches this statement. The next call to OCIStmtPrepare2() on this same session (by the same thread in our application) will re-use this already parsed statement. This saves soft parses at the server.


.

Examine the contents for the stage4.c file and compare it to stage3.c. You can use the tkdiff utility to view the differences.

Execute the following command to view the stage4.c and stage3.c files.

tkdiff stage3.c stage4.c

Note the differences in the files. In stage4.c OCI statement caching is enabled.

Note: If you are working in a Linux environment, you may need to change the permission to execute the stagen files. To do so, execute the following at the command prompt:


chmod 777 stage*
exit 

.

Use the gmake utility to build the executable C programs and library for the source code for stage4. Start a terminal window, navigate (by using the 'cd' command) to the location where the stage files are (/home/oci/ocilab) and execute the gmake utility

cd $HOME/oci/ocilab
gmake stage4

 

.

In your SQL*Plus session, run the reports.sql script. Pass to it the stage4 file. Add the parameter to iterate 1000 times to increase the workload and generate findings.

@reports.sql "../stage4 -i 1000"

As the report runs, you are shown the percentage completed.

.

When prompted for the report name, enter:
stage4_oci

This generates two reports which are saved in the current directory:

    • stage4_oci_addm.txt - the ADDM report.
    • stage4_oci_awr.html - the AWR report.

Generated sample results are provided to you for each stage. These files are located in the /home/oci/ocilab/doc sub-folder.. The names of the sample results files are:

    • stage4_results_addm.txt - the ADDM report.
    • stage4_results_awr.html - the AWR report.

Note: Your results may differ from the sample results provided due to environment differences. For consistency in this tutorial, the generated sample results are examined.

 

.

Examine the contents in the stage4_results.txt report.

(You can either open the file in a text editor, or you can scroll up in your SQL*Plus session.)

Note the summary of findings.

 

.

Examine the contents in the stage4_results_awr.htm report. Compare the parse calls in AWR with previous stage and see that it has decreased a lot. This is due to client-side statement caching.

Find the file stage4_results_awr.htm. Double-click the file name to open the file in a browser (or right-click and select the Open with "Web-Browser" option).

Review the report .

Scroll down to the Main Report. Click the SQL Statistics link.

Note the Elapsed time statistics. As you go through each of the stages and apply different tuning methods, these numbers will change (and improve).

 

Stage 5: OCI Client Result-Set Caching Enabled

This stage is same as stage4, but with client result set caching enabled. This is achieved by:

Notes:

  1. The client result cache needs to be enabled on the server using the initialization parameters shown below:
    • CLIENT_RESULT_CACHE_SIZE
    • CLIENT_RESULT_CACHE_LAG
    • Set COMPATIBLE to 11.2.0.0.0 (to get caching on views) otherwise, setting compatible to 11.1.0.0.0 will suffice. Note that you cannot change compatible to 11.1.0.0.0 once the database is started using a higher value 11.2.0.0.0.
  2. You can change the result cache setting for the regions table by executing this statement:
    'alter table regions result_cache (mode default)'
    This will make the OCI client look for any query level hints and since there are none, the query results in query_salary() will now not be cached.
  3. Query level hints over-ride the table annotations:
    • /*+ no_result_cache */ – this will ensure queries are not cached. The default is not cache the queries unless there is a
    • /*+ result_cache */ – query level hint or all the tables in the query are annotated for result caching.
  4. The method query_salary( ) has added an extra fetch call to get the error OCI_NO_DATA. This is to ensure that we have fetched all of the rows so the cached result set is available for cache matches subsequently.

.

You need to set up the regions table for result cache caching using the alter table DDL statement. The stage5.sql script contains the following statements:

-- STAGE 5
-- annotate table for result caching so queries on it can be cached on
-- client result cache
-- Doing below part of stage5 in separate script so can see
-- performance difference in AWR reports.
ALTER TABLE regions result_cache (mode force); QUIT;

In a SQL*Plus session, connect as the ocihol/welcome user and run the stage5.sql script:

CONNECT ocihol/welcome
@stage5.sql

 

.

Examine the contents for the stage5.c file and compare it to stage4.c. You can use the tkdiff utility to view the differences.

Execute the following command to view the stage5.c and stage4.c files.

tkdiff stage4.c stage5.c

Note the differences in the files. In the stage5.c file, OCI client result-set caching is enabled.

Note: If you are working in a Linux environment, you may need to change the permission to execute the stagen files. To do so, execute the following at the command prompt:


chmod 777 stage*
exit 

.

Use the gmake utility to build the executable C programs and library for the source code for stage5. Start a terminal window, navigate (by using the 'cd' command) to the location where the stage files are (/home/oci/ocilab) and execute the gmake utility

cd $HOME/oci/ocilab
gmake stage5

 

.

In your SQL*Plus session, run the reports.sql script. Pass to it the stage5 file. Add the parameter to iterate 1000 times to increase the workload and generate findings.

@reports.sql "../stage5 -i 1000"

As the report runs, you are shown the percentage completed.

.

When prompted for the report name, enter:
stage5_oci

This generates two reports which are saved in the current directory:

    • stage5_oci_addm.txt - the ADDM report.
    • stage5_oci_awr.html - the AWR report.

Generated sample results are provided to you for each stage. These files are located in the /home/oci/ocilab/doc sub-folder.. The names of the sample results files are:

    • stage5_results_addm.txt - the ADDM report.
    • stage5_results_awr.html - the AWR report.

Note: Your results may differ from the sample results provided due to environment differences. For consistency in this tutorial, the generated sample results are examined.

 

.

Examine the contents in the stage5_results.txt report.

(You can either open the file in a text editor, or you can scroll up in your SQL*Plus session.)

Note the summary of findings.

 

.

Examine the contents in the stage5_results_awr.htm report.

Find the file stage5_results_awr.htm. Double-click the file name to open the file in a browser (or right-click and select the Open with "Web-Browser" option).

Review the report .

Scroll down to the Main Report. Click the SQL Statistics link.

Note in the AWR section 'SQL Ordered by Executions' , the less number of executions to server for

i. SQL with query-level hint:

select /*+ result_cache */ empno, ename
from empview where empno > :EMPNO order by empno

and

ii. Query using result cache table annotation:

select region_id, region_name from regions where region_id = :regionID

Instead of 20 threads * 1000 iterations = 20,000 executions to server, both the above queries show much less executions to server. This will help SQL net traffic and CPU consumption.

Also, note there are updates but their frequency has been reduced from 20,000 to 200 (i.e. once every 100 iterations per thread). This is so cached result sets on client are not invalidated very frequently.

If you increase the frequency of updates (e.g. do it per iteration per thread) to table myemp you will see more server executions for query i above (with query-level hint on empview view), coming back to around 20,000. This is not recommended as client result cache is to be used on read only or read mostly data. Else you will incur expense in caching and invalidating the result-sets.

 

Stage 6: Using PL/SQL procedure and REF Cursors

In this stage, we illustrate support for PLSQL calls within OCI. The stored procedures are defined in the createtables.sql script and used by below new C methods added in this stage.