Karl about the Oracle Database

Some experiences out of my daily oracle practice

Archive for the '10.2' Category

Month ID generator

Posted by carl.reitschuster on 22nd May 2007

Hi reader,

if you have to deal with datawarehouses you need to implement dimension tables. A dimension could be the time dimension - a table of month Id’s for example to aggregate data per month. How to generate  such month id’s (YYYYMM)?

Simply use the model clause - some Oracle 10g spreadsheet functionality and generate a bunch of cells with specified rules.

To get a stream of years execute following SQL :


SELECT Integer_Value AS YEAR
 FROM Dual
 WHERE 1=2
 MODEL DIMENSION BY(0 AS Key)
       MEASURES(0 AS Integer_Value)
       RULES UPSERT(Integer_Value [ FOR KEY FROM 1900 TO 2100 INCREMENT 1 ] = Cv(KEY))


SQL> SELECT Integer_Value AS YEAR
  2    FROM Dual
  3   WHERE 1 = 2
  4   MODEL DIMENSION BY(0 AS Key)
  5         MEASURES(0 AS Integer_Value)
  6         RULES UPSERT(Integer_Value [ FOR KEY FROM 1900 TO 2100 INCREMENT 1 ] = Cv(KEY))
  7  ;
 
      YEAR
———-
      1900
      1901
      1902
      1903
      1904
      1905
      1906
      1907

To get a stream of months execute following statement


SELECT Integer_Value AS MONTH

  FROM Dual

 WHERE 1 = 2

 MODEL DIMENSION BY(0 AS Key)

       MEASURES(0 AS Integer_Value)

       RULES Upsert(Integer_Value [ FOR KEY FROM 1 TO 12 INCREMENT 1 ] = Cv(Key))

SQL> SELECT Integer_Value AS MONTH
  2    FROM Dual
  3   WHERE 1 = 2
  4   MODEL DIMENSION BY(0 AS Key)
  5         MEASURES(0 AS Integer_Value)
  6         RULES Upsert(Integer_Value [ FOR KEY FROM 1 TO 12 INCREMENT 1 ] = Cv(Key))
  7  ;
 
     MONTH
———-
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10
        11
        12
 
12 rows selected
 

To get the combination of both use cartesian product of month and year stream


SELECT YEAR , MONTH, (YEAR * 100) + MONTH AS MONTHID FROM (

  SELECT Integer_Value AS YEAR

    FROM Dual

   WHERE 1 = 2

   MODEL DIMENSION BY(0 AS Key)

         MEASURES(0 AS Integer_Value)

         RULES UPSERT(Integer_Value [ FOR Key FROM 1900 TO 2100 Increment 1 ] = Cv(Key))),

(

  SELECT Integer_Value AS MONTH

    FROM Dual

   WHERE 1 = 2

   MODEL DIMENSION BY(0 AS Key)

         MEASURES(0 AS Integer_Value)

         RULES UPSERT(Integer_Value [ FOR KEY FROM 1 TO 12 INCREMENT 1 ] = Cv(Key))) 

 

SQL> SELECT YEAR , MONTH, (YEAR * 100) + MONTH AS  MONTHID FROM (
  2    SELECT Integer_Value AS YEAR
  3      FROM Dual
  4     WHERE 1 = 2
  5     MODEL DIMENSION BY(0 AS Key)
  6           MEASURES(0 AS Integer_Value)
  7           RULES UPSERT(Integer_Value [ FOR Key FROM 1900 TO 2100 Increment 1 ] = Cv(Key))),
  8  (
  9    SELECT Integer_Value AS MONTH
 10      FROM Dual
 11     WHERE 1 = 2
 12     MODEL DIMENSION BY(0 AS Key)
 13           MEASURES(0 AS Integer_Value)
 14           RULES UPSERT(Integer_Value [ FOR KEY FROM 1 TO 12 INCREMENT 1 ] = Cv(Key)))
 15  ;
 
      YEAR      MONTH    MONTHID
———- ———- ———-
      1900          1     190001
      1900          2     190002
      1900          3     190003
      1900          4     190004
      1900          5     190005
      1900          6     190006
      1900          7     190007
      1900          8     190008
      1900          9     190009
      1900         10     190010
      1900         11     190011
      1900         12     190012
      1901          1     190101

Now you get your monthid without writing one line of PL/SQL or the need of base data.

HTH Karl Reitschuster

 

Posted in 10.2, SQL | No Comments »

SuSE Linux 10.1 and Oracle 10.2 64bit installation

Posted by carl.reitschuster on 18th April 2007

Hi reader,

some aspects i need to remember in future installation i want to record here. SuSE Linux 10.1 is different from the SLES/OpenSuSE  Installations. Libraries,  Development Tools, … are missing.

In order to run Oracle 10G installation on SuSE 10.1 you must

  • use DVD Media - only on DVD the 64Bit packages are available. Otherwise you could do a network install.
  • create Oracle user with dba as primary group
  • Install the C/C++ Compiler packages - without them you cannot relink the oracle binaries during installation

    gcc-c++ - The GNU C++ Compiler

  • Install 32bit shared and development libraries

    glibc-32bit - Standard Shared Libraries (from the GNU C Library)
    glibc-devel-32bit - Include Files and Libraries Mandatory for Development

  • Install the orarun package
  • Support for Asyncronus I/O

    libaio - Linux-Native Asynchronous I/O Access Library

  • Do not set LD_LIBRARY_PATH - sounds interesting ;-)

    unset LD_LIBRARY_PATH

  • starting installer with disabling the check of the Operatingsystem.

runInstaller -ignoreSysPrereqs

With these settings i could install Oracle 10.2 on SuSE Linux 10.1 on AMD 64bit.

Some additional configuration is needed if you want to setup a database

  • ulimit - added by orarun tool in  /etc/security/limits.conf

## added by orarun ##
oracle  soft    nproc   2047
oracle  hard    nproc   16384
oracle  soft    nofile  1024
oracle  hard    nofile  65536
# End of file

  • shared memory parameters - once you installed the orarun package :

/usr/sbin/rcoracle start  # sets SHM paramter
/sbin/chkconfig oracle on # sets SHM parameter during startup

  • Uncomment 127.0.0.2 ip address for Hostname and enter the real address for proper access via dbconsole

#127.0.0.2       sv019291.dev.global.taxi.com sv019291
150.179.37.146  sv019291.dev.global.taxi.com sv019291

  • ORA-27102: out of memory/Linux-x86_64 Error: 28: No space left on device
    you have to size shared memory properly. Shared memory must be large enough for all started instances.
    But not all physical memory must be allocated; The Value should by <= 75% of total physical memory.

(TotalAllocatedSGA(all instances) < (shmall * PageSize) )
&&
( (shmall * PageSize) <= (TotalPhysicalMemory / 100 ) * 75
)

retrieving Memory pagesize :  getconf PAGE_SIZE

retrieving shmall setting : cat /proc/sys/kernel/shmall

  • The network card settings should be checked. Sometimes due to a mismatch of duplex settings for example network speed could drop down < 10%
    ;

    view the settings of your servers network card interface eth0 :
    ethtool eth0

    set network card properties (interface eth0 *only* for example!) : 
    ethtool -s eth0 speed 100 duplex full autoneg off

Will complete the list in future

Karl Reitschuster

Links …

The Installation Guide for SLES 10 : Oracle 10g R2 (10.2.0.1) on SUSE Linux Enterprise Server 10

The Installation Guide for OpenSuSE : Oracle Database10g R2 (10.2.0.1) on openSUSE 10.2

Setting Shared Memory (Puschitz) : Tuning and Optimizing Red Hat Enterprise Linux for Oracle 9i and 10g Databases

Blog of proper setting of SHMALL : It’s an SGA Explosion

Posted in 10.2, Linux | 2 Comments »

Oracle (10g) Tuning Quickstart Guide

Posted by carl.reitschuster on 2nd March 2007

Hi reader,

you find it here

HTH

Karl

Posted in UnCategorized, Tuning, 10.2 | No Comments »

The LIKE Bindvariable Dilemma

Posted by carl.reitschuster on 20th February 2007

hi,

everybody tells you to use bind variables (reduced parses) and that’s ok. But in some circumstances you get a lot of problems with it. Using bind variables with the LIKE operator could cause horrible performance even you index that column and you do not use a ‘%’ at the start of the searched string.

Case 1 comparing with = operator :

WHERE Company.Customer = :P02

                  TABLE ACCESS BY LOCAL INDEX ROWID Depth=18 Object owner=ISIS Object name=COMPANY Cost=4 CPU cost=28254 IO cost=4 Cardinality=1 Bytes=289   Options=BY LOCAL INDEX ROWID  Operation=TABLE ACCESS Optimizer=ANALYZED Partition id=18 Partition start=2 Partition stop=2
                   INDEX RANGE SCAN Depth=19 Object owner=ISIS Object name=COMPANY_IX01 Cost=3 CPU cost=21764 IO cost=3 Cardinality=1  Access predicates="COMPANY"."CUSTOMER"=:P02  Options=RANGE SCAN  Operation=INDEX Optimizer=ANALYZED Partition id=19 Partition start=2 Partition stop=2

Yeah!! the optimizer chooses the index - very fast response - in this case.

Case 2 comparing with LIKE operator :

WHERE Company.Customer LIKE :P02

                  TABLE ACCESS FULL Depth=18 Object owner=ISIS Object name=COMPANY Cost=45241 CPU cost=8354827075 IO cost=44959 Cardinality=346919 Bytes=100259591  Filter predicates="COMPANY"."CUSTOMER" LIKE :P02 Options=FULL  Operation=TABLE ACCESS Optimizer=ANALYZED Partition id=27 Partition start=2 Partition stop=2

Oh my god!!! what is Oracle doing here???? Full Tablescan over 6.6m rows. The reason for is that dummy 5% assumption. Oracle assumes to scan 5% rows (look at the expected cardinality it’s about 5% of 6.8m) of the table using LIKE with bind var. Unfortunately this is the limit for a full table scan.

We fixed that with a higher affinity to index blocks. Also there is an internal parameter known to cahnge globally the way oracle calculate the expected cardinality of the LIKE operator. But a better way in the future release of the software will be: If the queried field is full qualified (means full length without ‘%’ or ‘_’) then the comparison operator is used instead of like.

cheers

Karl

 

Posted in Tuning, 9.2, 10.2, Statistics, Execution Plan, advanced, 10.1 | No Comments »

Scalability : About

Posted by carl.reitschuster on 26th January 2007

Hi reader,

after a benchmarking test of Components of a CRM System with Oracle 10.2 and Sun Solaris with either AMD Opteron or Sun SPARC IV+ CPU’s i started to think about the definition of Scalability. Her it is:

Scalability is about how strong the increase 
of the Throughput/decrease of Response Time
of an Application or Software Component is
when additional resources of CPU, Memory and I/O are added;

A second one follows :

Scalability is about how strong the decrease
of the Throughput/increase of Response Time
of an Application or Software Component is
when the workload ( Amount of work, Amount of Concurrency ) increases;

Karl Reitschuster

Posted in Tuning, 10.2 | 2 Comments »

Nice Load Graph seen in DB Console

Posted by carl.reitschuster on 12th December 2006

Hi reader,

looked during a data load via SQL*LOADER on the top Activity page of the Oracle Db Console and was fascinated by these tree very nice painted bands of CPU,COMMIT and User I/O . Some kind of beauty ;-)

 

HTH :-)
Karl Reitschuster

 

 

Posted in UnCategorized, 10.2, Db Console | No Comments »

Pinning very large objects into the KEEP pool

Posted by carl.reitschuster on 11th December 2006

Hi reader,

Once an Oracle Block is read from the disk it gets a place in the buffer cache. How long the block remains cached depends on following parameters.

  • if it’s an index block - they are stronger bound to the DEFAULT cache then table blocks resulting in a longer period of cache life cycle.
  • if it’s a table block - it will be cached but earlier freed from cache then an index block
  • if it’s a frequently accessed (LRU mechanism) a block frequently access will remain in the buffer cache
  • if the table block is originated by a long full table scan - a block read by a scattered read on a table which does not fit in a scan window of the buffer cache - it will be displaced immediately from the next blocks.

To guarantee a longer life cycle for a table/index block another cache type i think was introduced with Oracle 8i. The KEEP pool. It tends to keep (to pin) the blocks even they are not frequently accessed and enables caching of all blocks of a segment read with scattered read and not only a subset of it. Thus it is guaranteed that access to a segment cached in KEEP pool will not have any physical I/O. Usually i learnt to keep frequently small objects for example lookup tables into the KEEP pool.

We faced a problem on our company table querying specific company types a full table scan could not prevented. If many columns are used in some reports/lists to filter the result you cannot put an index on every column of the table. The company table is about 1.7G large with about 6.5M of rows. On our test database server two concurrent queries on the company table resulted in  > 60sec instead of 25sec. And even 25 sec are too long.

Having a 64 bit system we decided to upgrade memory and to pin the Company table into the KEEP pool.

Following steps to load the company table int o the KEEP pool:

  • set SGA_TARGET to 2.8G - Database is in automatic SGA sizing mode - a restart of the database will be needed
    ALTER SYSTEM SET sga_target=2800M SCOPE=SPFILE
    ;
  • and then set DBA_KEEP_POOL_SIZE to 1.8G - This reduces available memory for other SGA (Shared pool + DEFAULT buffer cache) components to 1G 
    ALTER SYSTEM SET db_keep_cache_size=1800M SCOPE=BOTH
    ;
  • Altered the tables buffer cache
    ALTER TABLE COMPANY STORAGE (BUFFER_POOL KEEP)
    ;
  • Pin the Company Table with a FULL table scan into the keep pool. ( You must use a FULL Hint to prevent an index full scan)
    SQL> SELECT /*+FULL (COMPANY)*/ COUNT(*) FROM COMPANY;
      COUNT(*)
    ———-
       6764758
    SQL>

once loaded the table into the KEEP buffer cache the result of the query response time was < 5sec even with concurrent sessions;

Monitor Buffer Pool Usage (the physical reads on the KEEP pool were caused by the inital load (pin) of the COMPANY Table):

SQL> SELECT Vps.NAME,
  2         Vps.Consistent_Gets,
  3         Vps.Physical_Reads
  4    FROM V$BUFFER_POOL_STATISTICS Vps;

NAME                 CONSISTENT_GETS PHYSICAL_READS
——————– ————— ————–
KEEP                        35762385         194722
DEFAULT                    306683092        3568628

SQL>

To go this way successfully you need following resources

  • fast CPU; for high LIO-Rate - on our Dual Xeon’s we had a rate of 1.4G/sec
  • higher number of CPU >= 4
  • Server optimized Mainboard/Memory access
  • fast Memory

Conclusion

If your site drives a 64bit System. You could benefit from loading very large objects into the KEEP pool. Sure - this is not an all round optimisation for your weak SQL and your weak physical and logical design of your database/schema
;-)

HTH
Karl Reitschuster

 

Posted in Tuning, 9.2, 10.2, advanced, 10.1 | No Comments »

Some issues with my Oracle 10.2 Installation on SuSE 10.1 64Bit

Posted by carl.reitschuster on 16th November 2006

Hi Reader,

had some problems with the installation i want to mention for myself to remember next time;

Strange security settings of Oracle Software Directories

Problems started as i wanted to config another user on the database server for SQL*PLUS Access. Even my setting of LD_LIBRARY_PATH/PATH/ORACLE_HOME was correct i got following message starting SQL*PLUS :

sqlplus: error while loading shared libraries: libsqlplus.so: cannot open shared object file: No such file or directory

The reason was the setting of the priviliges of these very important oracle runtime directories

drwxr-x-.-.-  3 oracle dba  7184 2006-11-03 15:16 lib
drwxr-x-.-.-  3 oracle dba  5144 2006-11-03 15:16 lib32

to access these directories you must at least in the dba unix group. I wondered about it. Probably an initial umask setting of the oracle user?

[ svx66287 /opt/oracle/102 ]
 ISISP [102] oracle > umask
0022

As workaround i put the user into the dba group which is not very secure. if you have any idea please let me know. As is said all works fine with the oracle user.

Karl

 

Posted in 10.2, Linux | No Comments »

Slow Tablespace Query Performance with Db Console and full RECYCLEBIN$

Posted by carl.reitschuster on 8th November 2006

Hi Reader,

after installing Oracle 10.2 64bit on Suse Linux 10.1 I started the dbconsole. A page i visited soon was Tablespace page. Usually on our Windows Server 2003 32Bit system, with the same Oracle version, the Tablespace query lasts for about 20 seconds! On the Linux System with the same number of Application tablespaces the Query response time was < 0.5 seconds. I thought this could not be the result being on just another operating system or driving the database with 64bit.

After reviewing the explain plan i detected the access to the Table RECYCLEBIN$; As by default Tables dropped are moved logically to the RECYCLEBIN$; The segments remain until the place in the tablespace exceeds; And now I recognized a big difference; On the slow system the RECYCLEBIN$ had about 2,600 rows on the fast system only 16 rows.

I started to purge all these tables of the different users and believe me or not the Query got faster and faster; Now with 12 rows I have the same response time for both Systems Linux 64 bit / Windows 2003 32 Bit;

So keep your Oracle 10.2 RECYCLEBIN$ as small as possible;

HTH Karl Reitschuster

The Query :

SELECT Dtp.Tablespace_Name "TABLESPACE_NAME",
       Dtp.Status "STATUS"
,
       Dtp.
Contents "CONTENTS",
       Dtp.Extent_Management "EXTENT MANAGEMENT"
,
       Dtp.Allocation_Type "ALLOCATION TYPE"
,
       Dtp.
Logging "LOGGING",
       Nvl
(Ts.Bytes,
          
0) "SIZE (M)",
       Dtp.Initial_Extent "INITIAL EXT SIZE (K)"
,
       Dtp.Next_Extent "Next Extent"
,
       Dtp.Pct_Increase "INCREMENT PCT"
,
       Dtp.Max_Extents "MAX EXTENTS"
,
       Nvl
(Ts.Bytes - Nvl(f.Bytes,
                         
0),
          
0) "USED BYTES"
 
FROM Sys.Dba_Tablespaces Dtp,

      
(SELECT Tablespace_Name,
              
SUM(Bytes) Bytes
         
FROM
Dba_Data_Files
         
GROUP BY Tablespace_Name) Ts,

      
(SELECT Tablespace_Name,
              
SUM(Bytes) Bytes
         
FROM
Dba_Free_Space
        
GROUP BY Tablespace_Name)
f
 
WHERE Dtp.Tablespace_Name = Ts.Tablespace_Name(+)

  
AND Dtp.Tablespace_Name = f.Tablespace_Name(+)
  
AND NOT
       
(Dtp.Extent_Management LIKE ‘LOCAL’ AND Dtp.Contents LIKE ‘TEMPORARY’)
UNION ALL
SELECT Dtp.Tablespace_Name "TABLESPACE_NAME",
       Dtp.Status "STATUS"
,
       Dtp.
Contents "CONTENTS",
       Dtp.Extent_Management "EXTENT MANAGEMENT"
,
       Dtp.Allocation_Type "ALLOCATION TYPE"
,
       Dtp.
Logging "LOGGING",
       Nvl
(a.Bytes,
          
0) "SIZE (M)",
       Dtp.Initial_Extent "INITIAL EXT SIZE (K)"
,
       Dtp.Next_Extent "Next Extent"
,
       Dtp.Pct_Increase "INCREMENT PCT"
,
       Dtp.Max_Extents "MAX EXTENTS"
,
       Nvl
(t.Bytes,
          
0) "USED BYTES"
 
FROM Sys.Dba_Tablespaces Dtp,

      
(SELECT Tablespace_Name,
              
SUM(Bytes) Bytes
         
FROM
Dba_Temp_Files
         
GROUP BY Tablespace_Name) a,

      
(SELECT Ss.Tablespace_Name,
              
SUM((Ss.Used_Blocks * Ts.Blocksize)) Bytes
         
FROM Gv$sort_Segment Ss,

              
Sys.Ts$         Ts
        
WHERE Ss.Tablespace_Name = Ts.NAME

        
GROUP BY Ss.Tablespace_Name) t
 
WHERE Dtp.Tablespace_Name = a.Tablespace_Name(+)

  
AND Dtp.Tablespace_Name = t.Tablespace_Name(+)
  
AND Dtp.Extent_Management LIKE ‘LOCAL’
  
AND Dtp.Contents LIKE ‘TEMPORARY’

 

Posted in 10.2, Db Console | 2 Comments »

Experiencing ASH and extended trace 10046 event

Posted by carl.reitschuster on 31st October 2006

Hi Reader,

Inserting on a table with a lot of indexes could cause the wait event db file sequential read. For every row to be inserted the index must be scanned and updated when an indexed column was specified in the DML statement. With about 150 rows a second the insert operation was very slow. I enabled extended trace 10046 event and reviewed the generated raw trace file;

The traditionaly way - trace files

In the 10046 event trace file you will find the Cursor definiton section of the insert statement:


=====================

PARSING IN CURSOR #8 len=693 dep=1 uid=50 oct=2 lid=50 tim=226692485 hv=1579689243 ad=’396bb604

INSERT INTO COMPANY () VALUES (:B18 , NULL, 0, NULL, NULL, SYS_GUID(), :B17 , NULL, NULL,