Tuesday, February 14, 2012

gathering system stats

The workload needs to be very exhaustive to gather the correct set of values - a good mix of sessions some doing multi-block reads and others sequential reads. I tried to capture these stats using three different workloads, and the stats had a stark variation.
Workload1: created two indexes on a fact table.
Workload2: Executed 8 BI queries in parallel.
Workload3: Executed a bi query making it fairly complex by self joining the fact table.

These are the results:


Workload1 Workload2 Workload3
CPUSPEED 948 948 916
CPUSPEEDNW 948 948 948
IOSEEKTIM 5 5 5
IOTFRSPEED 91662 91662 91662
MAXTHR 311120896 129651712 360448
MBRC
3 6
MREADTIM 16.741 2419.531 35318.899
SLAVETHR 5065728 4799488 4799488
SREADTIM
547.395 331.686

11.2 has a bug which miscalculates MREAD and SREAD time inflating them by a factor of 1000:
Bug 9842771 - Wrong SREADTIM and MREADTIM statistics in AUX_STATS$ [ID 9842771.8]


best is to set these stats manually:
http://www.dbi-services.com/index.php/blog/entry/problem--strange-figures-while-collecting-the-oracle-optimizer-system-statistics-


Both these link are mentioned in Jonathan blog post - http://jonathanlewis.wordpress.com/category/oracle/statistics/system-stats/.


Further to this, as far as I understand the absolute values of these two attributes MREADTIM and SREADTIM is something that is inconsequential. Its the ratio of these two that drives optimizer to choose between Full table scan or Index scans.

Monday, June 27, 2011

Establishing remote connection to DB2 Server


To be able to use db2 connect from client, there are few configuration steps to be followed as mentioned here:

on DB2 Server

db2set DB2COMM=tcpip
update database manager configuration using svcename 50000
db2stop
db2start

on Client Side

db2 UNCATALOG DATABASE db_name
db2 UNCATALOG DCS DATABASE db_name
db2 UNCATALOG NODE server_name
db2 CATALOG TCPIP NODE server_name REMOTE server_name SERVER 50000 REMOTE_INSTANCE DB2 SYSTEM server_name OSTYPE AIX
db2 CATALOG DCS DATABASE db_name AS db_name
db2 CATALOG DATABASE db_name AS db_name AT NODE server_name AUTHENTICATION DCS 


$ db2 connect to db_name user user_name using password

   Database Connection Information

 Database server        = DB2/AIX64 9.1.6
 SQL authorization ID   = user_name
 Local database alias   = db_name

Thursday, October 7, 2010

Intra-Block versus Inter-Block row chaining

Oracle database can store only 255 columns in a single row-piece. Anything beyond 255 columns will be stored as a separate row, chained to the main one. This kind of chaining is different from what we know as migrated/chained rows which happen either because of lack of space in current block which causes rows to migrate when updated leaving behind their new address or due to row size more than the block size itself. Both these types of chaining are inter-block row chaining.

intra-block row chaining (as i mentioned above happens due to number of columns exceeding 255) does not cause as much a performance issue as inter-block row chaining. This is because all the row contents could still be found within the same block. When there is a full table scan, DB can easily do scattered reads over this table with number of blocks spanning up to the value for parameter db_file_multiblock_read_count. For scanning rows which are chained to another block, as is the case with migrated/chained rows, DB has to do sequential reads with one block read at a time. This summarily degrades query performance.

Unlike Inter-block row chaining, Intra-block row chaining cannot be detected using ANALYZE TABLE LIST CHAINED ROWS command. However, there is a way to see to what extent the rows are chained. Look out for statistic " table fech continued row". As you access the table with 255+ columns, this value will keep increasing.

 select name, value from v$sysstat where name like 'table fetch %';


Note that if all the columns beyond 255 columns have NULL values, the row will not be chained.

Monday, May 10, 2010

BI Apps ETL: Handling statistics gathering over tables in parallel

For one of the BI Apps incremental ETL execution, it was observed that the major time is consumed during statistics gathering over some of the warehouse tables. There were three tables which took 1 hr each to execute. When run standalone, gathering statistics over each of these tables took only 3 minutes. So, what was so wrong during the ETL ??

Upon closely observing the DAC execution plan it was found that all these three tables were analyzed in parallel. It was not a coincidence. In fact, each time these three tables would land up being analyzed in parallel. So, the question is how come !!!
There was a task group defined which had collection of six tasks which where loading into these three tables. Truncate table option was enabled over this task group. This caused all query indexes to be created over these three tables once all the tasks in this task group finished loading these three tables. While query indexes were created in parallel and one table had all indexes created while the other tables still had them being created, statistics gathering over the table did not spawn. Only after all the three tables had all the indexes created, analyze command over the three table was fired. This caused all these three tables getting created in parallel. Is executing these three tables in parallel so much resource consuming that time taken jumped 20 times than when run one at a time ??

Lets see the command being used to analyze these tables:

exec DBMS_STATS.GATHER_TABLE_STATS(ownname => USER, tabname => 'W_TAB_D', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, method_opt => 'FOR ALL INDEXED COLUMNS SIZE AUTO',cascade => false ,degree =>DBMS_STATS.AUTO_DEGREE );

When I executed all three tables in parallel, maximum time taken by any of analyze commands was 26 minutes (during etl there were some more Informatica jobs running which would have further slowed it down to take 1 hr). This is what I observed in v$sysstat view:

Before firing all three commands in parallel:
---------------------------------------------------
Parallel operations not downgraded                                        9
Parallel operations downgraded to serial                               0

After firing all three commands in parallel:
----------------------------------------------------
Parallel operations not downgraded                                       10
Parallel operations downgraded to serial                               2

This shows that all the parallel servers were put to use by analyze over one of the table and rest of the two were then executed serially. This serial execution caused the other two analyze to take more time.

Now, the option was to either segregate the tasks with in the task group in three different task groups, or, to do something to speed up the analyze over these three tables in parallel.

First option was not so enticing given that this task group is shipped OOTB and any changes might impact the functionality. Also, all the tasks in this task groups were loading different tables in a given order, so changing the order by segregating them in different task groups was not so straight forward. So, the choice left was to speed up the statistics gathering over the table.

Since it was observed that parallel servers were hogged by analyze over one single table, It was decided to override the degree parameter in the analyze command and set it a value so that all the three execution will get enough parallel servers. We may not get the performance as that of standalone execution, but it might still be better than what was observed.

So, the revised syntax is:
exec DBMS_STATS.GATHER_TABLE_STATS(ownname => USER, tabname => 'W_TAB_D', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, method_opt => 'FOR ALL INDEXED COLUMNS SIZE AUTO',cascade => false ,degree =>4);

When executed in parallel, the maximum time taken by any of these stands at 19 minutes. v$sysstat shows no jobs being downgraded to serial.
Parallel operations not downgraded                                       16
Parallel operations downgraded to serial                               2

This brought about performance improvement of 27%. Obviously, it is yet to be seen how it fares when we incorporate these changes in DAC for etl purpose. Will post more on what further is found.




Thursday, January 28, 2010

Upgrading AIX system to next Technology Level

Refer to below link for upgrading technology level:
http://www.ibm.com/developerworks/aix/library/au-aixservicepacks/index.html

As root user:
# suma -c -a HTTP_PROXY=http://[proxy]:[port]/
# suma -c -a FTP_PROXY=http://[proxy]:[port]/
#smit suma
-> select option "Download Updates Now"
-> select "Download Maintenance Level or Technology Level
-> Provide TL as 5300-07 for e.g.

Once all files are downloaded. Start installation.

# inutoc
# smit update_all
-> provide the directory for software as "/usr/sys/inst.images"
-> toggle the "Accept new license agreement" to Yes.
-> [Enter]
-> [Enter]. 
-> Upgrade starts...
 

Thursday, January 7, 2010

DAC: no db2jdbc in java.library.path

This error is generated when you try to establish connection to DB2 using DAC even if you have db2java.zip present in lib directory.

To resolve this issue, edit \dac_env.bat and add \SQLLIB\bin to path variable.

Sunday, December 6, 2009

Oracle : Values of Hidden init parameters

Hiddle parameter values can not be accessed using v$parameter view. Use the following script:


SELECT
x.ksppinm name,
y.ksppstvl VALUE,
decode(ksppity,
1, 'BOOLEAN',
2, 'STRING',
3, 'INTEGER',
4, 'PARAMETER FILE',
5, 'RESERVED',
6, 'BIG INTEGER',
'UNKNOWN') typ,
decode(ksppstdf,
'TRUE', 'DEFAULT VALUE',
'FALSE', 'INIT.ORA') isdefault,
decode(bitand(ksppiflg / 256, 1),
1, 'IS_SESS_MOD(TRUE)',
'FALSE') isses_modifiable,
decode(bitand(ksppiflg / 65536, 3),
1, 'MODSYS(NONDEFERED)',
2, 'MODSYS(DEFERED)',
3, 'MODSYS(*NONDEFERED*)',
'FALSE') issys_modifiable,
decode(bitand(ksppstvf, 7),
1, 'MODIFIED_BY(SESSION)',
4, 'MODIFIED_BY(SYSTEM)',
'FALSE') is_modified,
decode(bitand(ksppstvf, 2),
2, 'ORA_STARTUP_MOD(TRUE)',
'FALSE') is_adjusted,
ksppdesc description,
ksppstcmnt update_comment
FROM x$ksppi x,
x$ksppcv y
WHERE x.inst_id = userenv('Instance')
AND y.inst_id = userenv('Instance')
AND x.indx = y.indx
AND x.ksppinm LIKE '%pga%';

Wednesday, November 18, 2009

Configure DBD::ODBC on AIX 5.3

DBD::ODBC perl module helps connecting to various datasources using ODBC. In order to get this module working, one needs to install unixodbc on aix platform.

1.Download unixODBC-2.2.11
- Version 2.2.14 has some issues causing installation to fail.
2.
export CC=xlc_r
export CCC=xlC_r

3. For 64 bit OS
export OBJECT_MODE=64
export CFLAGS=-q64

It is possible to install 32 bit binaries on 64 bit OS. Just do not set the above two variables.

4 Execute configure
./configure --prefix=/opt/unixODBC --disable-gui CC=xlc_r CXX=xlC_r
make
make install

5. Generate shared object libraries (/opt/unixODBC/lib)
ar -x libodbc.a
ar -x libodbcinst.a
ar -x libodbccr.a

5. Set the following environment variables

export ODBCINI=/usr/scratch/odbc.ini
export ODBCHOME=/opt/unixODBC
export LIBPATH=/opt/unixODBC/lib:${LIBPATH}


If perl is already installed, install module DBI and then DBD::ODBC. For new install follow the procedure mentioned below:

1. Download perl 5.10.1

2 If OS is 64 bit use flag -Duse64bitall
sh Configure -Duse64bitall -Dprefix=/opt/perl -des
make
make install

To install 32 bit perl binaries, do not use flag -Duse64bitall

3. Configure CPAN. First configure it in default mode. Then make changes to the proxy settings
cpan> o conf init /proxy/
--specify ftp_proxy and http_proxy to be used
cpan> 0 conf commit

4. Install DBI module
cpan> install DBI

5. install DBD::ODBC
cpan> install DBD::ODBC

you should be all set to use perl DBD::ODBC module !!!

Monday, November 16, 2009

CPAN : reset proxy settings

To reset proxy setting for CPAN

CPAN> o conf init /proxy/


setting root prompt with sudo access

If you have sudo access to a machine, it is convenient to set root prompt and then execute commands instead of using "sudo command " everytime.


"sudo su -" would get you the root prompt.

Wednesday, October 7, 2009

Removing Oracle 11gR2 software

To clean up the installed Oracle 11gR2 software, execute the deinstall script. It is present in $ORACLE_HOME/deinstall directory.

$ORACLE_HOME/deinstall/deinstall
Checking for required files and bootstrapping ...
Please wait ...
Location of logs /scratch/Oracle/OraInventory/logs/

############ ORACLE DEINSTALL & DECONFIG TOOL START ############


######################## CHECK OPERATION START ########################
Install check configuration START


Checking for existence of the Oracle home location /scratch/Oracle11gr2/product/11.2.0/dbhome_1
Oracle Home type selected for de-install is: SIDB
Oracle Base selected for de-install is: /scratch/Oracle11gr2
Checking for existence of central inventory location /scratch/Oracle/OraInventory

Sunday, June 7, 2009

Informatica : Setting codepage

Informatica integration service sometimes fails with the following error when trying to startup:
LM_36011
Code page mismatch. Service process is running in code page [ISO 8859-1 Western European] whereas the service is configured in the Admin Console to run in code page [UTF-8 encoding of Unicode]

Set the following environment variables on the Linux based server hosting Informatica nodes:
setenv LANG en_US.utf8
setenv LC_ALL en_US.utf8
setenv INFA_CODEPAGENAME UTF-8

For windows, set environment variables LC_ALL and LANG to us_UTF8

Re-start the node service.

Now, integration service can be started with codepage set to UTF-8.

Sunday, April 26, 2009

Oracle : Using WITH Clause for improving performance

Many times using inline views destroy the execution plans. This is mainly because the execution plan of inline view interfere with the overall execution plan of the query.

To counter this, inline view can be taken to the top inside WITH clause. But this alone will not help. We need to incorporate hint /*+ materialize */ , as only then database treats the view as a physical table. Database creates a temporary table out of the view which is then used in the query. Execution plan is found far improved than before.


Query with following structure showed nested loop join between tables tab1 and tab2. This mainly was influenced by the inline view. Specifying USE_HASH hint also does not work.

SELECT col1,
col2,
Sum(col4)
FROM tab1,
tab2,
(SELECT DISTINCT Last_day(To_date(dates,'DD-MM-YYYY')) end_dt,
Add_months(Last_day(To_date(dates,'DD-MM-YYYY')) + 1,
-1) strt_dt,
To_char(To_date(dates,'DD-MON-YYYY'),'MMYYYY') mon_dt
FROM (SELECT To_char(Add_months(SYSDATE,-10) + (LEVEL - 1),'DD-MON-YYYY') AS dates
FROM dual
CONNECT BY To_number(To_char((Add_months(SYSDATE,-10) + (LEVEL - 1)),'YYYYMMDD')) <= To_number(To_char(SYSDATE,'YYYYMMDD')))) tim
WHERE tab1.assign_dt <= tim.end_dt
AND tab1.assign_dt >= tim.strt_dt
AND tab1.col3 = tab2.col3
GROUP BY col1,
col2

Changing the query to the following using WITH caluse leads to perfect execution plan using HASH join .


WITH TIM as (
(SELECT /*+ materialize */ DISTINCT Last_day(To_date(dates,'DD-MM-YYYY')) end_dt,
Add_months(Last_day(To_date(dates,'DD-MM-YYYY')) + 1,
-1) strt_dt,
To_char(To_date(dates,'DD-MON-YYYY'),'MMYYYY') mon_dt
FROM (SELECT To_char(Add_months(SYSDATE,-10) + (LEVEL - 1),'DD-MON-YYYY') AS dates
FROM dual
CONNECT BY To_number(To_char((Add_months(SYSDATE,-10) + (LEVEL - 1)),'YYYYMMDD')) <= To_number(To_char(SYSDATE,'YYYYMMDD'))))
)
SELECT col1,
col2,
Sum(col4)
FROM tab1,
tab2,
tim
WHERE tab1.assign_dt <= tim.end_dt
AND tab1.assign_dt >= tim.strt_dt
AND tab1.col3 = tab2.col3
GROUP BY col1,
col2


Tuesday, April 14, 2009

DB2 : collecting detailed statistics

to get the best optimizer execution plan, collecting detailed table statisitics might help:

db2 -x -r "runstats.db2" "select rtrim(concat('runstats on table ',concat(rtrim(tabSchema),concat('.',concat(rtrim(tabname),' on all columns with distribution on all columns and sampled detailed indexes all allow write access'))))) from syscat.tables where type='T'"
db2 -v -f "runstats.db2"

Tuesday, April 7, 2009

DB2 : Generating SQL Explain plan

This is how explain plan can be generated in DB2 database.

Create a file statements.db2:
select deptno from dept@

db2expln -database U001DB -stmtfile statements.db2 -terminator @ -terminal -user siebel siebel

Section Code Page = 1252

Estimated Cost = 30087412.000000
Estimated Cardinality = 19275950.000000

Access Table Name = SIEBEL.S_ORG_EXT ID = 7,201
| #Columns = 2
| Relation Scan
| | Prefetch: Eligible
| Lock Intents
| | Table: Intent Share
| | Row : Next Key Share
| Sargable Predicate(s)
| | Process Build Table for Hash Join
Left Outer Hash Join
| Early Out: Single Match Per Outer Row
| Estimated Build Size: 7776000
| Estimated Probe Size: 9948879872
| Access Table Name = SIEBEL.S_ORG_EXT ID = 7,201
| | #Columns = 2
| | Relation Scan
| | | Prefetch: Eligible
...
...

Monday, April 6, 2009

INFORMATICA : Truncate Logs

There was an unusual behavior when i proceeded with repository manager to truncate the existing session logs. Option "Truncate Log" under "Edit" menu was disabled. Selecting/expanding the required folder also did not help.

Since my informatica server was on AIX with client on windows, i did the following to truncate the logs:

$ pmrep
pmrep>connect -r Powercenter -d Domain_server1 -n Administrator -x Administrator

pmrep>truncatelog -t all
truncatelog completed successfully.

Sunday, April 5, 2009

DB2 : Establish remote connection on Unix/AIX

On server hosting DB2 Database:
db2set DB2COMM=tcpip
update database manager configuration using svcename 50000
db2stop
db2start

On client server (with DB2 client installed)
db2 UNCATALOG DATABASE U001DB
db2 UNCATALOG DCS DATABASE U001DB
db2 UNCATALOG NODE SERVER1

db2 CATALOG TCPIP NODE SERVER1 REMOTE SERVER1 SERVER 50000 REMOTE_INSTANCE DB2 SYSTEM SERVER1 OSTYPE AIX
db2 CATALOG DCS DATABASE U001DB AS U001DB
db2 CATALOG DATABASE U001DB AS U001DB AT NODE SERVER1 AUTHENTICATION DCS

Where, SERVER1 is the server where db2 server resides. U001DB is the db2 database name.

Test connection:

On client server:
db2 connect to U001DB user siebel using siebel

Database Connection Information

Database server = DB2/AIX64 9.1.6
SQL authorization ID = SIEBEL
Local database alias = U001DB

Tuesday, February 24, 2009

Oracle :Outer Join pitfalls

Starting Oracle 10G, Optimizer processes outer joins in much efficient way. Execution plan now has "HASH JOIN RIGHT OUTER", which means that the table with scant records will be scanned first. Table which it is outer joined to will be scanned in the end. This is especially use full for Datawarehouse queries where Fact table is outer joined to lot of dimension tables. So, DB now does not have to temp read and write the fact table records to join them later to the dimension tables.

But, before one jumps into concluding that this new method is almost sure way to win, there are few things one should keep in mind.
1. Ensure NOPARALLEL query execution. This new execution plan for outer joins is severely affected by parallel query i.e. if dimension tables are scanned in parallel and then joined to the fact tables, query exhibits worst performance. To avoid parallel execution, check that tables or any participating indexes have degree set to "1". Alternatively, one an also disable parallel query execution at instance level by setting init parameter "max_parallel_servers" to "0". But this is no advisable as there could be other kind of queries which might want to leverage the advantages of parallel query execution.

2. Keep huge dimension tables out of the outer joins. If Dimension tables (the one which is outer joined) is huge, lets say...1 Million records (for pga 4 gig), outer join using new execution plan may not help. This is because now hash tables for all the joining dimension could not be kept in memory and DB anyways have to do multipass hash join. "HASH JOIN RIGHT OUTER" based execution plan is effective only if the outer joined tables/dimensions are smaller in size.

3. Ensure that all the participating tables has the statistics collected. Missing statistics on tables would cause optimizer to pick up execution plan as it existed before 10G and you may not see the new execution plan for outer joined query.

Thursday, January 15, 2009

Informatica 8.6 : issue with pmcmd

On AIX 5.3 pmcmd command fails with following error:

$ ./pmcmd

Could not load program ./pmcmd:
Could not load module /u01/Informatica/PowerCenter8.6/server/bin/libpmser.a.
Dependent module /lib/libz.a could not be loaded.
The module has an invalid magic number.
Could not load module pmcmd.
Dependent module /u01/Informatica/PowerCenter8.6/server/bin/libpmser.a could not be loaded.
Could not load module .

This issue has been fixed on one of the latest hotfixes.

To workaround the issue, rename /lib/libz.a so that libz.a which is shipped with Informatica is picked up.