DBMS Tuning & My Life

TUXEDO 11gR1 Installation Guide for Beginner.

leave a comment »

Recently, I installed TUXEDO 11gR1 on my test system. Actually, the installation isn’t difficult, if you’re already familiar with TUXEDO enviroment. But, If you aren’t, maybe you will undergo trial and error. Below is the steps of installation.

(1) Download the TUXEDO engine.
Download the TUXEDO engine.
I downloaded “Oracle Tuxedo 11gR1 (11.1.1.3.0) for Linux x86-64 (64-bit)” and that file name is tuxedo111130_64_Linux_01_x86.bin.

(2) Engine installation on the server.
2.1 Upload the tuxedo engine file to the server by FTP
2.2 Below is the steps of TUXEDO engine installation
tux01

tux02

tux03

tux04

tux05

tux06

(3) Create a O/S user for TUXEDO and setup the environment.
[root@rac1 ~]# useradd -d /home/tuxadm -g oinstall -s /bin/bash tuxadm
[root@rac1 ~]# passwd tuxadm
Changing password for user tuxadm.
New UNIX password: ********
Retype new UNIX password: ********
passwd: all authentication tokens updated successfully.

[root@rac1 ~]# chown -R tuxadm:oinstall /ora01/tuxedo

[root@rac1 ~]# su - tuxadm

$ vi .bash_profile
export TMP=/tmp
export ORACLE_HOME=/ora01/app/oracle/product/11.2.0/db_1

export PATH=/usr/sbin:$PATH:$ORACLE_HOME/bin
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib;
export CLASSPATH=$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib;

export TUXDIR=/ora01/tuxedo/tuxedo11gR1
export JAVA_HOME=$TUXDIR/jre
export JVMLIBS=$JAVA_HOME/lib/i386/server
export PATH=.:$TUXDIR/bin:$JAVA_HOME/bin:$PATH
export COBCPY=:$TUXDIR/cobinclude
export COBOPT="-C ANS85 -C ALIGN=8 -C NOIBMCOMP -C TRUNC=ANSI -C OSEXT=cbl"
export SHLIB_PATH=$TUXDIR/lib:$JVMLIBS:$SHLIB_PATH
export LIBPATH=$TUXDIR/lib:$JVMLIBS:$LIBPATH
export LD_LIBRARY_PATH=$TUXDIR/lib:$JVMLIBS:$LD_LIBRARY_PATH
export WEBJAVADIR=$TUXDIR/udataobj/webgui/java
export APPS_HOME=$TUXDIR/APPS
export APPDIR=$TUXDIR/APPS
export TLOGDEVICE=$APPDIR/TLOG
export TUXCONFIG=$TUXDIR/APPS/tuxconfig
export ULOGPFX=$APPDIR/ULOG
export FLDTBLDIR=$TUXDIR/udataobj:$APPDIR
export WSNADDR=//192.168.0.50:9901

(4) Edit a ubbconfig file and compile the ubbconfig file.
$ cd $APPDIR
$ vi ubbconfig
*RESOURCES
IPCKEY 123456
MASTER SITE1
MAXACCESSERS 100
MAXSERVERS 20
MAXSERVICES 20
MODEL SHM
LDBAL N

*MACHINES
rac1 # The name of machine must same with the result of 'uname -n'.
LMID=SITE1
TUXDIR="/ora01/tuxedo/tuxedo11gR1"
APPDIR="/ora01/tuxedo/tuxedo11gR1/APPS"
TUXCONFIG="/ora01/tuxedo/tuxedo11gR1/APPS/tuxconfig"
ULOGPFX="/ora01/tuxedo/tuxedo11gR1/APPS/ULOG"
TLOGDEVICE="/ora01/tuxedo/tuxedo11gR1/APPS/TLOG"
TLOGNAME=TLOG
MAXWSCLIENTS=10

*GROUPS
DEFAULT: LMID=SITE1
GROUP1 GRPNO=1
TMSNAME=TMS_ORA11G TMSCOUNT=5
OPENINFO="Oracle_XA:Oracle_XA+SqlNet=ORA11G2+Acc=P/scott/tiger+SesTm=60"
WSGRP GRPNO=2

*SERVERS
DEFAULT: CLOPT="-A"
sel_his SRVGRP=GROUP1 SRVID=1
sel_his SRVGRP=GROUP1 SRVID=2
sel_his SRVGRP=GROUP1 SRVID=3
sel_his SRVGRP=GROUP1 SRVID=4
noarray_ins SRVGRP=GROUP1 SRVID=101
noarray_ins SRVGRP=GROUP1 SRVID=102
WSL SRVGRP=WSGRP SRVID=20
CLOPT="-A -- -d /dev/tcp -n //192.168.0.50:9901 -w WSH -m 1 -M 4 -x 10"
*SERVICES
DEFAULT: AUTOTRAN=N
SEL_HIS
INSERT

$ tmloadcf ubbconfig
Initialize TUXCONFIG file: /ora01/tuxedo/tuxedo11gR1/APPS/tuxconfig [y, q] ? y

(5) Make a TLOG file.
$ cd $APPDIR
$ vi crtlog.sh
if [ "${1}" = "-m" ] ; then
#
# If -m specified, create device and TLOG
#
tmadmin <<-!
echo
crdl -z ${TLOGDEVICE}
crlog -m SITE1
q
!
elif [ -z "${1}" ] ; then
#
# If -m not specified, create device only
#
tmadmin -c <<-!
echo
crdl -z ${TLOGDEVICE}
q
!
else
#
# If other things specified, error
#
echo "$0: usage: $0 [-m]"
exit 2
fi

if [ ${?} -eq 0 ] ; then
echo "`basename ${0}` successful."
exit 0
fi

$ chmod 755 crtlog.sh
$ crtlog.sh -m
tmadmin - Copyright (c) 1996-2010 Oracle.
Portions * Copyright 1986-1997 RSA Data Security, Inc.
All Rights Reserved.
Distributed under license by Oracle.
Tuxedo is a registered trademark.
No bulletin board exists. Entering boot mode.

> Echo now on.

> crdl -z /ora01/tuxedo/tuxedo11gR1/APPS/TLOG
Device created: /ora01/tuxedo/tuxedo11gR1/APPS/TLOG

> crlog -m SITE1
crlog successfully completed.

> q
crtlog.sh successful.

(6) Build TMS server for XA transaction.
$ cd $APPDIR
$ buildtms -o TMS_ORA11G -r Oracle_XA
$ cp TMS_ORA11G $TUXDIR/bin

(7) Boot TUXEDO engine

Written by sean70kim

July 19, 2013 at 7:04 am

Posted in Oracle

Tagged with ,

How to create an excel pivot table.

leave a comment »

Pivot table is very powerful, and very easy to use.

Whenever, our team members participate in the tuning project, we usaually use excel to manage the result of tuning. And pivot table is very useful, when we give a summary report to customers. Also,it’s very easy to use.
Below is the standard format for tuning report. It has a very detailed information, but it’s hard to see using the Module Code and Status.

excel01

 

 

 

 

 

So, customers want to see the statistic report through Module Code and Status. At a time like this, we use the pivot table.

1) select all cells
2) Menu-> Insert -> Pivot table
3) Locate Field to proper Area like this

excel02

4) It’s all over, Below is the result of pivot table.

excel03

Written by sean70kim

July 10, 2013 at 1:13 am

Posted in Scribbling

Tagged with ,

Do you want to check the I/O performance of your database machine?

leave a comment »

Sometimes, we need to check the I/O performance of our database machine. For example, after migrating to a new machine, specific file I/O moves too slow and etc. In that case, what is the most useful tool? Maybe, ORION is the best tool to satisfy all your needs. ORION stands for ORacle IO Numbers. And ORION was included in Oracle 11gR2. So, you can find ORION executable file under $ORACLE_HOME/bin directory.
The usage of ORION is very simple. With “-help” command wil give detail usage how to use ORION.
Now, let’s try to test.

1) First of all, we must edit orion.lun file which is located in $ORACLE_HOME/bin.
In my case, I want to check the I/O performance of undo datafile only. So, edit orion.lun file like follwing.

$ cd $ORACLE_HOME/bin
$ vi orion.lun
/oradata/undotbs01.dbf

2) Run orion.
Types of workload to run are simple, normal, advanced, dss, olpt. You can find the explanations of these options, with “-help” command. I choose the simple option.

$ ORACLE_HOME/bin/orion -run simple

ORION: ORacle IO Numbers -- Version 11.2.0.3.0
orion_20130521_1540
Calibration will take approximately 9 minutes.
Using a large value for -cache_size may take longer.

3) Analysis the output files
The number of output files is 5. You can also find the explanations of these files, with “-help” command. Anyway, The files that i interested are “orion__mbps.csv” and “orion__iops.csv”. The maximum Large MBPS=14.28 which is Small=#0 and Large=#2. MBPS stands for Mega Bits Per Second.

$ cat orion_20130521_1417_mbps.csv
Large/Small, 0, 1, 2, 3, 4, 5
1, 13.02
2, 14.28

The maximum small IOPS=219 which is Small=#5 and Large=#0. IOPS stands for IO counts Per Second.

$ cat orion_20130521_1417_iops.csv
Large/Small, 1, 2, 3, 4, 5
0, 138, 166, 194, 206, 219
1
2

The another tool for I/O calibration is DBMS_RESOURE_MANAGER.calibrate_io procedure. The usage and ouput are like following. The unit of actual_latency is millisecond (1/1,000). And, I recommand that this procedure don’t run in working time. Because, when you issue this procedure, oracle forks many background processes and run simultaneously.

SQL> set serveroutput on 

DECLARE
  l_latency  PLS_INTEGER;
  l_iops     PLS_INTEGER;
  l_mbps     PLS_INTEGER;
BEGIN
   DBMS_RESOURCE_MANAGER.calibrate_io (num_physical_disks => 1,
                                       max_latency        => 20,
                                       max_iops           => l_iops,
                                       max_mbps           => l_mbps,
                                       actual_latency     => l_latency);

  DBMS_OUTPUT.put_line('Max IOPS = ' || l_iops);
  DBMS_OUTPUT.put_line('Max MBPS = ' || l_mbps);
  DBMS_OUTPUT.put_line('Latency  = ' || l_latency);
END;
/

Max IOPS = 156
Max MBPS = 10 
Latency  = 18

Written by sean70kim

July 9, 2013 at 1:37 am

How to turn on the Adaptive Cursor Sharing at statement level even though, _optim_peek_user_binds=false.

leave a comment »

Although, the Adaptive Cursor Sharing(ACS) is a very useful feature, but, if you experiences some performance problem of bind peeking, maybe you turn off the bind peeking feature(_optim_peek_user_binds=false). In my previous post, I mentioned that if you turn off the bind peeking then the ACS won’t work.

In this case, we use OPT_PARAM and BIND_AWARE hint for using ACS at statement level.

 SQL> show parameter _optim

NAME                                 TYPE                   VALUE
------------------------------------ ---------------------- ------------------------------
_optim_peek_user_binds               boolean                FALSE
_optimizer_adaptive_cursor_sharing   boolean                FALSE
_optimizer_extended_cursor_sharing_r string                 NONE
el


var b1 number
exec :b1:=10;
 
select /*+BIND_AWARE opt_param('_optim_peek_user_binds','true') */
       count(*), max(c1), avg(c1)
from   t1
where  c2=:b1;
 
  COUNT(*)    MAX(C1)    AVG(C1)
---------- ---------- ----------
         1         10         10

select * from table(dbms_xplan.display_cursor);

SQL_ID  2xsn3xundg0yz, child number 0
-------------------------------------------------------------------------------------
| Id  | Operation                    | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |      |       |       |     2 (100)|          |
|   1 |  SORT AGGREGATE              |      |     1 |    17 |            |          |
|   2 |   TABLE ACCESS BY INDEX ROWID| T1   |     1 |    17 |     2   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN          | IDX1 |     1 |       |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------

select child_number, executions, buffer_gets,
       is_bind_sensitive, is_bind_aware
from   v$sql
where  sql_id='2xsn3xundg0yz';

CHILD_NUMBER EXECUTIONS BUFFER_GETS IS_BIND_SENSITIVE IS_BIND_AWARE
------------ ---------- ----------- ----------------- -------------
           0          1           3 Y                 Y

exec :b1:=1001; 

select /*+BIND_AWARE opt_param('_optim_peek_user_binds','true') */
       count(*), max(c1), avg(c1)
from   t1
where  c2=:b1;
 

  COUNT(*)    MAX(C1)    AVG(C1)
---------- ---------- ----------
     99000     100000    50500.5

 
SQL_ID  2xsn3xundg0yz, child number 1
---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |       |       |  4134 (100)|          |
|   1 |  SORT AGGREGATE    |      |     1 |    17 |            |          |
|*  2 |   TABLE ACCESS FULL| T1   | 99016 |  1643K|  4134   (1)| 00:00:50 |
---------------------------------------------------------------------------

select child_number, executions, buffer_gets,
       is_bind_sensitive, is_bind_aware
from   v$sql
where  sql_id='2xsn3xundg0yz';

CHILD_NUMBER EXECUTIONS BUFFER_GETS IS_BIND_SENSITIVE IS_BIND_AWARE
------------ ---------- ----------- ----------------- -------------
           0          1           3 Y                 Y
           1          1       14593 Y                 Y

Written by sean70kim

July 9, 2013 at 1:29 am

The behavior of BIND_AWARE hint.

leave a comment »

Oracle supports BIND_AWARE and NO_BIND_AWARE hints that could control the Adaptive Cursor Sharing. From the name of each hint, We could expect the behavior. The test of NO_BIND_AWARE hint is unnecessary. That hint is so clear. But, BIND_AWARE hint isn’t clear to me. So let’s try to test.

BIND_AWARE hint.
For the test, the disable parameter value would be needed.

alter session set "_optimizer_adaptive_cursor_sharing"=false;
alter session set "_optimizer_extended_cursor_sharing_rel"=false;

Next, execute query using hint. The test environment is all same as previous post.
From the test result, we know that BIND_WARE hint works well regardless of the parameter value.

var b1 number
exec :b1:=10; 
 
select /*+BIND_AWARE*/
       count(*), max(c1)
from   t1
where  c2=:b1;
  
  COUNT(*)    MAX(C1)
---------- ----------
         1         10 
 
select * from table(dbms_xplan.display_cursor);

SQL_ID  9avbm7xarm430, child number 0
------------------------------------------------------------------------------------
| Id  | Operation                    | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |      |       |       |     2 (100)|          |
|   1 |  SORT AGGREGATE              |      |     1 |    17 |            |          |
|   2 |   TABLE ACCESS BY INDEX ROWID| T1   |     1 |    17 |     2   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN          | IDX1 |     1 |       |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------

select child_number, executions, buffer_gets,
       is_bind_sensitive, is_bind_aware
from   v$sql
where  sql_id='9avbm7xarm430';
CHILD_NUMBER EXECUTIONS BUFFER_GETS IS_BIND_SENSITIVE IS_BIND_AWARE
------------ ---------- ----------- ----------------- -------------
           0          1           3 Y                 Y
    
exec :b1:=1001;
 
select /*+BIND_AWARE*/
       count(*), max(c1)
from   t1
where  c2=:b1;
  COUNT(*)    MAX(C1)
---------- ----------
     99000     100000
  
SQL_ID  9avbm7xarm430, child number 1
---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |       |       |  4134 (100)|          |
|   1 |  SORT AGGREGATE    |      |     1 |    17 |            |          |
|*  2 |   TABLE ACCESS FULL| T1   | 99016 |  1643K|  4134   (1)| 00:00:50 |
---------------------------------------------------------------------------
 
select child_number, executions, buffer_gets,
       is_bind_sensitive, is_bind_aware
from   v$sql
where  sql_id='9avbm7xarm430';
 
CHILD_NUMBER EXECUTIONS BUFFER_GETS IS_BIND_SENSITIVE IS_BIND_AWARE
------------ ---------- ----------- ----------------- -------------
           0          1           3 Y                 Y
           1          1       14593 Y                 Y

After the test, I wonder that BIND_AWARE hint can even work, even if “_optim_peek_user_binds”=false? As expected, if “_optim_peek_user_binds”=false then ACS can’t work. Because, if you turn off the feature of bind peeking then the oracle doesn’t peek any bind variable.

alter session set "_optim_peek_user_binds"=false; 
var b1 number
exec :b1:=10;
 
select /*+BIND_AWARE*/
       count(*), max(c1), min(c1)
from   t1
where  c2=:b1;
 
  COUNT(*)    MAX(C1)    MIN(C1)
---------- ---------- ----------
         1         10         10
 
select * from table(dbms_xplan.display_cursor);

SQL_ID  1wx1pmnfj5ajp, child number 0
-------------------------------------------------------------------------------------
| Id  | Operation                    | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |      |       |       |    16 (100)|          |
|   1 |  SORT AGGREGATE              |      |     1 |    17 |            |          |
|   2 |   TABLE ACCESS BY INDEX ROWID| T1   |   100 |  1700 |    16   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN          | IDX1 |   100 |       |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------
 
select child_number, executions, buffer_gets,
       is_bind_sensitive, is_bind_aware
from   v$sql
where  sql_id='1wx1pmnfj5ajp';
 
CHILD_NUMBER EXECUTIONS BUFFER_GETS IS_BIND_SENSITIVE IS_BIND_AWARE
------------ ---------- ----------- ----------------- -------------
           0          1           3 N                 N 

Written by sean70kim

July 9, 2013 at 1:19 am

Posted in Oracle

Tagged with , , ,

The mechanism of Adaptive Cursor Sharing.

leave a comment »

Adaptive Cursor Sharing(ACS) was introduced in oracle 11g. Until 10g, the oracle only supports bind peeking (from 9i). But, bind peeking has a big problem, when the column in the where clause with the bind has a skew data.To solve that problem ACS need to use a column histogram. Now, try to test to understand the ACS.

(1) Create a table and insert skew data.

create table t1 (c1 number, c2 number, dummy char(1000));
 
insert into t1
select level, level, 'dummy'
from   dual
connect by level<=1000
union all
select level+1000, 1001, 'dummy'
from   dual
connect by level<=99000;
 
commit; 
 
create index idx1 on t1(c2) nologging;
exec dbms_stats.gather_table_stats(user,'T1', method_opt=>'FOR ALL INDEXED COLUMNS SIZE 254');

(2) c2 column has (HEIGHT BALANCED) histogram.

select column_name, histogram from user_tab_columns where table_name='T1'
order by column_id;
 
COLUMN_NAME  HISTOGRAM
-----------  ----------------
C1           NONE
C2           HEIGHT BALANCED
DUMMY        NONE

(3) Now, let’s try to test.
The value of all hidden parameters that was related to ACS are default (_optimizer_adaptive_cursor_sharing=true, _optimizer_extended_cursor_sharing_rel=simple). First bind value is 10 and the number of rows is 1, so optimizer decided to index scan. it was good choice.

var b1 number
exec :b1:=10;
 
select /*_ACS1*/
       count(*), max(c1)
from   t1
where  c2=:b1;
 
  COUNT(*)    MAX(C1)
---------- ----------
         1         10
 
select * from table(dbms_xplan.display_cursor);
 
SQL_ID  as9xzr2tdxj5u, child number 0
-------------------------------------------------------------------------------------
| Id  | Operation                    | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |      |       |       |     2 (100)|          |
|   1 |  SORT AGGREGATE              |      |     1 |    17 |            |          |
|   2 |   TABLE ACCESS BY INDEX ROWID| T1   |     1 |    17 |     2   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN          | IDX1 |     1 |       |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------

And that cursor was marked IS_BIND_SENSITIVE=’Y’.

select child_number, executions, buffer_gets,
       is_bind_sensitive, is_bind_aware
from   v$sql
where  sql_id='as9xzr2tdxj5u';
 
CHILD_NUMBER EXECUTIONS BUFFER_GETS IS_BIND_SENSITIVE IS_BIND_AWARE
------------ ---------- ----------- ----------------- -------------
           0          1           3 Y                 N

Second bind value is 1001 and the number of rows is 99,000. So, in this case, full scan is better than index scan. But, against my expectations, the optimizer still has been decided to do index scan.
exec :b1:=1001;

 
select /*_ACS1*/
       count(*), max(c1)
from   t1
where  c2=:b1;
 
  COUNT(*)    MAX(C1)
---------- ----------
     99000     100000
 
select * from table(dbms_xplan.display_cursor);
 
SQL_ID  as9xzr2tdxj5u, child number 0
-------------------------------------------------------------------------------------
| Id  | Operation                    | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |      |       |       |     2 (100)|          |
|   1 |  SORT AGGREGATE              |      |     1 |    17 |            |          |
|   2 |   TABLE ACCESS BY INDEX ROWID| T1   |     1 |    17 |     2   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN          | IDX1 |     1 |       |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------

If that statement was executed one more time by same bind value (1001), then oracle will create a new child cursor(#1) and the optimizer will do full scan. And then, that cursor was marked IS_BIND_AWARE=’Y’.

select /*_ACS1*/
count(*), max(c1)
from t1
where c2=:b1;
 
 COUNT(*) MAX(C1)
---------- ----------
    99000 100000
 
select * from table(dbms_xplan.display_cursor);
         
SQL_ID  as9xzr2tdxj5u, child number 1
---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |       |       |  4134 (100)|          |
|   1 |  SORT AGGREGATE    |      |     1 |    17 |            |          |
|*  2 |   TABLE ACCESS FULL| T1   | 99016 |  1643K|  4134   (1)| 00:00:50 |
---------------------------------------------------------------------------
 
select child_number, executions, buffer_gets,
       is_bind_sensitive, is_bind_aware
from   v$sql
where  sql_id='as9xzr2tdxj5u';
 
CHILD_NUMBER EXECUTIONS BUFFER_GETS IS_BIND_SENSITIVE IS_BIND_AWARE
------------ ---------- ----------- ----------------- -------------
           0          2       14356 Y                 N
           1          1       14593 Y                 Y
 
The third bind value is 20 and the number of rows is 1. When we execute that sql statement, oracle creates a new child cursor(#2) and optimizer decided to index scan. From that time, the child cursor (#0) was no longer be used. That was marked IS_SHAERABLE='N'.
exec :b1:=20
 
elect /*_ACS1*/
       count(*), max(c1)
from   t1
where  c2=:b1;
 
select * from table(dbms_xplan.display_cursor);
 
SQL_ID  as9xzr2tdxj5u, child number 2
-------------------------------------------------------------------------------------
| Id  | Operation                    | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |      |       |       |     2 (100)|          |
|   1 |  SORT AGGREGATE              |      |     1 |    17 |            |          |
|   2 |   TABLE ACCESS BY INDEX ROWID| T1   |     1 |    17 |     2   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN          | IDX1 |     1 |       |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------
 
select child_number, executions, buffer_gets,
       is_bind_sensitive, is_bind_aware, is_shareable
from   v$sql
where  sql_id='as9xzr2tdxj5u';
 
CHILD_NUMBER EXECUTIONS BUFFER_GETS IS_BIND_SENSITIVE IS_BIND_AWARE IS_SHAREABLE
------------ ---------- ----------- ----------------- ------------- ------------
           0          2       14356 Y                 N             N
           1          1       14593 Y                 Y             Y
           2          1           3 Y                 Y             Y

Written by sean70kim

July 9, 2013 at 1:11 am

Posted in Oracle

Tagged with ,

The simple example of unpivot.

leave a comment »

Unpivot provides very conveninent way, when we search on v$sql_shared_cursor view.
When, we want to know the reason of multiple child cursors, we look at the v$sql_shared_cursor view. But, that view isn’t user-friendly. In this case, we can use unpivot feature from oracle 11g like this. The oracle version of test environment is 11.2.0.3.

-- fnd_shared_cursor.sql
 
WITH v1 AS (
          SELECT *
          FROM   v$sql_shared_cursor
          WHERE  sql_id=:sql_id 
     )
SELECT sql_id ,
       child_number ,
       reason_type ,
       result
FROM   v1
unpivot (result FOR reason_type IN
(
-- columns are vary depend on oracle version
"UNBOUND_CURSOR",
"SQL_TYPE_MISMATCH",
"OPTIMIZER_MISMATCH",
"OUTLINE_MISMATCH",
"STATS_ROW_MISMATCH",
"LITERAL_MISMATCH",
"FORCE_HARD_PARSE",
"EXPLAIN_PLAN_CURSOR",
"BUFFERED_DML_MISMATCH",
"PDML_ENV_MISMATCH",
"INST_DRTLD_MISMATCH",
"SLAVE_QC_MISMATCH",
"TYPECHECK_MISMATCH",
"AUTH_CHECK_MISMATCH",
"BIND_MISMATCH",
"DESCRIBE_MISMATCH",
"LANGUAGE_MISMATCH",
"TRANSLATION_MISMATCH",
"BIND_EQUIV_FAILURE",
"INSUFF_PRIVS",
"INSUFF_PRIVS_REM",
"REMOTE_TRANS_MISMATCH",
"LOGMINER_SESSION_MISMATCH",
"INCOMP_LTRL_MISMATCH",
"OVERLAP_TIME_MISMATCH",
"EDITION_MISMATCH",
"MV_QUERY_GEN_MISMATCH",
"USER_BIND_PEEK_MISMATCH",
"TYPCHK_DEP_MISMATCH",
"NO_TRIGGER_MISMATCH",
"FLASHBACK_CURSOR",
"ANYDATA_TRANSFORMATION",
"PDDL_ENV_MISMATCH",
"TOP_LEVEL_RPI_CURSOR",
"DIFFERENT_LONG_LENGTH",
"LOGICAL_STANDBY_APPLY",
"DIFF_CALL_DURN",
"BIND_UACS_DIFF",
"PLSQL_CMP_SWITCHS_DIFF",
"CURSOR_PARTS_MISMATCH",
"STB_OBJECT_MISMATCH",
"CROSSEDITION_TRIGGER_MISMATCH",
"PQ_SLAVE_MISMATCH",
"TOP_LEVEL_DDL_MISMATCH",
"MULTI_PX_MISMATCH",
"BIND_PEEKED_PQ_MISMATCH",
"MV_REWRITE_MISMATCH",
"ROLL_INVALID_MISMATCH",
"OPTIMIZER_MODE_MISMATCH",
"PX_MISMATCH",
"MV_STALEOBJ_MISMATCH",
"FLASHBACK_TABLE_MISMATCH",
"LITREP_COMP_MISMATCH",
"PLSQL_DEBUG",
"LOAD_OPTIMIZER_STATS",
"ACL_MISMATCH",
"FLASHBACK_ARCHIVE_MISMATCH",
"LOCK_USER_SCHEMA_FAILED",
"REMOTE_MAPPING_MISMATCH",
"LOAD_RUNTIME_HEAP_FAILED",
"HASH_MATCH_FAILED",
"PURGED_CURSOR",
"BIND_LENGTH_UPGRADEABLE",
"USE_FEEDBACK_STATS")
)
where result='Y';
 
--Sample Output
SQL_ID        CHILD_NUMBER  REASON_TYPE          RESULT
c9q44tap900dw 1             EXPLAIN_PLAN_CURSOR  Y
c9q44tap900dw 2             EXPLAIN_PLAN_CURSOR  Y

Written by sean70kim

July 9, 2013 at 12:00 am

Posted in Oracle

Tagged with ,

The simple example of MODEL clause.

leave a comment »

In my previous post, i mentioned about partition outer join to make report layout.
There is another way to make a report layout using a model clause like this. It just sample for learning to MODEL clause.

 
WITH v1 AS (
           SELECT a.site ,
                  a.item ,
                  a.category ,
                  SUM( a.amount ) amount
           FROM   t2 a
           GROUP  BY a.site ,
                  a.item ,
                  a.category
     )
select s, i, c, a
from   v1
Spreadsheet
partition by (site s, item i)
dimension by (category c)
measures (amount a)
rules
(
  a['C01'] = PRESENTV(a['C01'], a['C01'], 0),
  a['C02'] = PRESENTV(a['C02'], a['C02'], 0),
  a['C03'] = PRESENTV(a['C03'], a['C03'], 0),
  a['C04'] = PRESENTV(a['C04'], a['C04'], 0),
  a['C05'] = PRESENTV(a['C05'], a['C05'], 0),
  a['C06'] = PRESENTV(a['C06'], a['C06'], 0),
  a['C07'] = PRESENTV(a['C07'], a['C07'], 0),
  a['C08'] = PRESENTV(a['C08'], a['C08'], 0),
  a['C09'] = PRESENTV(a['C09'], a['C09'], 0),
  a['C10'] = PRESENTV(a['C10'], a['C10'], 0)
)
order by s,i,c
 
call     count       cpu    elapsed       disk      query    current       rows        mis   Wait Ela
------- ------  -------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
Parse        1      0.25       1.90        451        277          1          0          1       0.00
Exec         1      0.00       0.00          0          0          0          0          0       0.00
Fetch    40000    143.09     197.66     101622      22029         17     999995          0     191.56
------- ------  -------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
Total    40002    143.34     199.55     102073      22306         18     999995          1     191.56
 
Event waited on                             Count Zero Ela     Elapse   AVG(Ela)   MAX(Ela)   Blocks
---------------------------------------- -------- -------- ---------- ---------- ---------- --------
Disk file operations I/O                        1        0       0.00       0.00       0.00        0
direct path write temp                       1561        0      41.10       0.03       0.28        0
SQL*Net message to client                   40001        0       0.26       0.00       0.00        0
direct path read                               67        0       1.39       0.02       0.25        0
SQL*Net message from client                 40001        0     153.81       0.00      18.39        0
direct path read temp                        1194        0      13.38       0.01       0.19        0
 
Rows       Row Source Operation
---------- ---------------------------------------------------
    999995 SORT ORDER BY (cr=22029 pr=101622 pw=79781 time=178073503 us cost=6243 size=226319654 card=709466)
    999995  SQL MODEL ORDERED FAST (cr=22029 pr=61614 pw=39773 time=67399100 us cost=6243 size=226319654 card=709466)
    499995   HASH GROUP BY (cr=22029 pr=39883 pw=18042 time=30056894 us cost=6243 size=226319654 card=709466)
    499995    TABLE ACCESS FULL T2 (cr=22029 pr=21841 pw=0 time=2490717 us cost=6089 size=226319654 card=709466) 

Written by sean70kim

July 8, 2013 at 11:58 pm

Posted in Oracle

Tagged with

You can use hint using pg_plan_hint for PostgreSQL.

leave a comment »

Sourceforge.JP offers pg_plan_hint for PostgreSQL for free.

In my previous post, I mentioned about a hint for PostgreSQL. But, if you just need hint feature in EDB(enterprise database), the cost of EDB might be a little expensive. And, according to http://wiki.postgresql.org/wiki/OptimizerHintsDiscussion, postgresql has no plan about hint. So, if you just need the hint feature, you can consider the pg_plan_hint. The pg_plan_hint is provided by sourceforge.JP. The usage of pg_plan_hint is similar with oracle. Actually, I don’t know, pg_plan_hint is bugfree. But, through my simple test, I think that pg_plan_hint can use in simple case. For the test, first of all, Let’s install the pg_plan_hint.

1) Download pg_plan_hint
http://en.sourceforge.jp/projects/pghintplan/
In my case, I downloaded “pg_hint_plan92-1.0.0.tar.gz” file.

2) File upload and extract file
> ftp hostip
user: ****
password: ***

$ gunzip pg_hint_plan92-1.0.0.tar.gz
$ tar xvf pg_hint_plan92-1.0.0.tar

3) Installation
$ cd pg_hint_plan92-1.0.0
--The value of PG_CONFIG is maybe diffent, depend on your environment.
$ make PG_CONFIG=/usr/local/pgsql/bin/pg_config
$ make PG_CONFIG=/usr/local/pgsql/bin/pg_config install

If you already installed PGXC, you meet the compile error like this.
pg_hint_plan.c:1554: warning: passing arg 6 of pointer to function makes integer from pointer without a cast
pg_hint_plan.c:1554: error: too few arguments to function
make: *** [pg_hint_plan.o] Error 1

Then, you just edit /usr/local/pgsql/include/server/tcop/utility.h for fix error.

$ vi /usr/local/pgsql/include/server/tcop/utility.h
#ifndef UTILITY_H
#define UTILITY_H
#include "tcop/tcopprot.h"
#undef PGXC -- add this line

-- Edit postgresql.conf file
$ cd /usr/local/pgsql/data/datanode1/
$ vi postgresql.conf
shared_preload_libraries='pg_hint_plan' -- add this line

-- restart pgsql
$ pg_ctl stop -D /usr/local/pgsql/data/datanode1 -m fast
$ pg_ctl start -D /usr/local/pgsql/data/datanode1 -Z datanode -l logfile

From now, we can use hint for pgsql. Let’s do a test.

(1) Create table/index and data loading.

create table t1 (c1 int, c2 int, c3 int, dummy char(100));
create index t1_idx1 on t1 (c1, c2, c3);
create index t1_idx2 on t1 (c2, c3);
create index t1_idx3 on t1 (c3);
create index t1_idx4 on t1 (c1); 
 
create table t2 (c1 int, c2 int, c3 int, dummy char(100));
create index t2_idx1 on t2 (c1, c2, c3);
create index t2_idx2 on t2 (c2, c3);
create index t2_idx3 on t2 (c3);
 
create table t3 (c1 int, c2 int, c3 int, dummy char(100));
create index t3_idx1 on t3 (c1, c2, c3);
create index t3_idx2 on t3 (c2, c3);
create index t3_idx3 on t3 (c3); 
 
insert into t1 select 1, mod(c1,100), mod(c1,1000), 'dummy' from generate_series(1,100000) c1;
insert into t2 select 1, mod(c1,100), mod(c1,1000), 'dummy' from generate_series(1,10000) c1;
insert into t3 select 1, mod(c1,100), mod(c1,1000), 'dummy' from generate_series(1,100) c1;

(2) The test of IndexScan and SeqScan hints.
In my test case, IndexScan and SeqScan hints are working very well.

/*+ IndexScan(t1 t1_idx1) */
explain analyze
select *
from   t1
where  c1=1
and    c2=10
and    c3=100

"Index Scan using t1_idx1 on t1  (cost=0.00..8.29 rows=1 width=113) (actual time=0.021..0.021 rows=0 loops=1)"
"  Index Cond: ((c1 = 1) AND (c2 = 10) AND (c3 = 100))"
"Total runtime: 0.056 ms"

/*+ IndexScan(t1 t1_idx4) */
explain analyze
select *
from   t1
where  c1=1
and    c2=10
and    c3=100

"Index Scan using t1_idx4 on t1  (cost=0.00..4923.26 rows=1 width=113) (actual time=99.512..99.512 rows=0 loops=1)"
"  Index Cond: (c1 = 1)"
"  Filter: ((c2 = 10) AND (c3 = 100))"
"Total runtime: 99.556 ms"

/*+ SeqScan(t1) */
explain analyze
select *
from   t1
where  c1=1
and    c2=10
and    c3=100

"Seq Scan on t1  (cost=0.00..3536.00 rows=1 width=113) (actual time=49.532..49.532 rows=0 loops=1)"
"  Filter: ((c1 = 1) AND (c2 = 10) AND (c3 = 100))"
"Total runtime: 49.571 ms"

(3) The test of Leading, NestLoop, HashJoin hints.
In my test case, all hints were working very well.
And the usage of NestLoop and HashJoin hints were are little different with oracle. Oracle uses one or two argument in use_nl and use_hash hints. For example, I want to use nested loops join with a, b, c table in order. In that case,
we use /*+ leading(a b c) use_nl(b) use_nl(c) */ or /*+ leading(a b c) use_nl(a b) use_nl(b c) */.
But, in case of pg_plan_hint, we use /*+ leading(a b c) NestLoop(a b) NestLoop(a b c) */.

/*+ Leading(c b a) NestLoop(c b) HashJoin(c b a) */
explain analyze
select a.*, b.*, c.*
from   t1 a, t2 b, t3 c
where  a.c1=b.c1
and    a.c2=b.c2
and    a.c3=b.c3
and    b.c1=c.c1
and    b.c2=c.c2
and    b.c3=c.c3
 
"Hash Join  (cost=504.08..4415.18 rows=10 width=339) (actual time=6.825..342.277 rows=100000 loops=1)"
"  Hash Cond: ((a.c1 = b.c1) AND (a.c2 = b.c2) AND (a.c3 = b.c3))"
"  ->  Seq Scan on t1 a  (cost=0.00..2786.00 rows=100000 width=113) (actual time=0.014..80.097 rows=100000 loops=1)"
"  ->  Hash  (cost=503.91..503.91 rows=10 width=226) (actual time=6.754..6.754 rows=1000 loops=1)"
"        Buckets: 1024  Batches: 1  Memory Usage: 244kB"
"        ->  Nested Loop  (cost=0.00..503.91 rows=10 width=226) (actual time=0.037..4.971 rows=1000 loops=1)"
"              Join Filter: (b.c1 = c.c1)"
"              ->  Seq Scan on t3 c  (cost=0.00..3.00 rows=100 width=113) (actual time=0.009..0.098 rows=100 loops=1)"
"              ->  Index Scan using t2_idx2 on t2 b  (cost=0.00..4.99 rows=1 width=113) (actual time=0.011..0.028 rows=10 loops=100)"
"                    Index Cond: ((c2 = c.c2) AND (c3 = c.c3))"
"Total runtime: 391.877 ms"
  
/*+ Leading(a b c) HashJoin(a b) NestLoop(a b c) */
explain analyze
select a.*, b.*, c.*
from   t1 a, t2 b, t3 c
where  a.c1=b.c1
and    a.c2=b.c2
and    a.c3=b.c3
and    b.c1=c.c1
and    b.c2=c.c2
and    b.c3=c.c3
 
"Nested Loop  (cost=625.00..14466.80 rows=10 width=339) (actual time=22.144..6251.758 rows=100000 loops=1)"
"  Join Filter: ((a.c1 = c.c1) AND (a.c2 = c.c2))"
"  ->  Hash Join  (cost=625.00..11600.00 rows=10000 width=226) (actual time=22.114..1928.040 rows=1000000 loops=1)"
"        Hash Cond: ((a.c1 = b.c1) AND (a.c2 = b.c2) AND (a.c3 = b.c3))"
"        ->  Seq Scan on t1 a  (cost=0.00..2786.00 rows=100000 width=113) (actual time=0.013..93.049 rows=100000 loops=1)"
"        ->  Hash  (cost=279.00..279.00 rows=10000 width=113) (actual time=22.019..22.019 rows=10000 loops=1)"
"              Buckets: 1024  Batches: 2  Memory Usage: 669kB"
"              ->  Seq Scan on t2 b  (cost=0.00..279.00 rows=10000 width=113) (actual time=0.008..8.505 rows=10000 loops=1)"
"  ->  Index Scan using t3_idx3 on t3 c  (cost=0.00..0.27 rows=1 width=113) (actual time=0.002..0.002 rows=0 loops=1000000)"
"        Index Cond: (c3 = a.c3)"
"Total runtime: 6308.625 ms"
 
/*+ Leading(a b c) NestLoop(a b) NestLoop(a b c) */
explain analyze
select a.*, b.*, c.*
from   t1 a, t2 b, t3 c
where  a.c1=b.c1
and    a.c2=b.c2
and    a.c3=b.c3
and    b.c1=c.c1
and    b.c2=c.c2
and    b.c3=c.c3
 
"Nested Loop  (cost=0.00..14722.40 rows=10 width=339) (actual time=0.067..8733.899 rows=100000 loops=1)"
"  Join Filter: ((a.c1 = c.c1) AND (a.c2 = c.c2))"
"  ->  Nested Loop  (cost=0.00..11855.60 rows=10000 width=226) (actual time=0.055..4084.912 rows=1000000 loops=1)"
"        Join Filter: (a.c1 = b.c1)"
"        ->  Seq Scan on t2 b  (cost=0.00..279.00 rows=10000 width=113) (actual time=0.014..10.070 rows=10000 loops=1)"
"        ->  Index Scan using t1_idx2 on t1 a  (cost=0.00..1.14 rows=1 width=113) (actual time=0.017..0.232 rows=100 loops=10000)"
"              Index Cond: ((c2 = b.c2) AND (c3 = b.c3))"
"  ->  Index Scan using t3_idx3 on t3 c  (cost=0.00..0.27 rows=1 width=113) (actual time=0.002..0.003 rows=0 loops=1000000)"
"        Index Cond: (c3 = a.c3)"
"Total runtime: 8791.946 ms"

Written by sean70kim

July 8, 2013 at 7:33 am

Posted in postgreSQL

Tagged with

The simple example of recursive subquery factoring.

leave a comment »

Maybe, recursive subquery factoring was used in few cases only. But in that case, recursive subquery factoring provides very convenient way to handle each node.

For example, there is a diagram like below and we want calculate the ela(psed time) to current node. Without the recursive subquery factoring, we shoud use sys_connect_by_path and user define function.

rsb

Read the rest of this entry »

Written by sean70kim

July 7, 2013 at 2:54 am

Posted in Oracle

Tagged with ,