Pages

Tuesday, April 6, 2010

Published my Second Oracle Technical Paper

Today, I have successfully published my Oracle Technical Paper titled "Database Disaster Recovery using only RMAN Backups" under My Oracle Support Community (formerly known as Oracle Customer Knowledge Exchange)
Link: https://communities.oracle.com/

The technical paper demonstrates how an Oracle Database can be recovered or reconstructed by using only the RMAN Backup files in case of a complete server crash. On this blog, you know it as "Disaster Recovery using RMAN Backups".

The access to the published document in My Oracle Support Community would require customer logon credentials. So if you are interested to know more about my technical paper, feel free to email me at zk.oracle@gmail.com for the PDF file.

Thursday, April 1, 2010

Default Sort Behavorial Change for GROUP BY queries without ORDER BY clause in Oracle 10g Database

After our successful production database migration to 10gR2 (10.2.0.4), we came across a few user complaining about sorting issue in specific screens. On further investigation, we found out that some screens having fields with list of data values were not ordered, as they were in 9iR2.

Upon a little googling we found an interesting case at Jaffar's blog "Change behavior of GROUP BY clause in Oracle 10g.". It seems he had faced the same issues when he migrated from 9i to 10g, and has well documented the case with resolution in his post.

Basically, in 9i, SQL Queries having the GROUP BY clause only had a default behavior of being ordered. These SQLs in 9i appeared sorted (despite any ORDER BY clause) because of the default sorting behavior seen in the execution plan as "SORT GROUP BY".

On the other hand, 10g now has a sorting behavorial change, in which the SQL Queries having the GROUP BY clause only with no ORDER BY clause, there will be no default sorting done, which is seen in the execution plan as "HASH GROUP BY".

The 3 possible resolutions are as follows:
  1. Change the affected SQL Queries to embedd ORDER BY Clause, or
  2. Set "_gby_hash_aggregation_enabled" = FALSE at session level or system level, or
  3. Set optimizer_features_enabled=9.2.0
In our case, as we have 3rd party ERP software, we don't have the source code of most of the affected screens. So, we could not choose the 1st option entirely (except for reports, and backend queries). Choosing the 3rd option defeats to purpose of migrating to 10g as most of the 10g optimizatin features will not be available, but this option was the last resort. We tested out the 2nd option and it worked perfectly fine.

Let me demonstrate how I implemented the 2nd option on my production 10gR2 database.

Before changing "_gby_hash_aggregation_enabled" parameter:

SQL> set autotrace on
SQL> select owner,count(1) from dba_objects where object_type='VIEW' group by owner;


OWNER COUNT(1)
------------------------------ ----------
WKSYS 79
MDSYS 59
DMSYS 1
WK_TEST 6
CTXSYS 54
SYSTEM 12
EXFSYS 56
DBSNMP 1
ORDSYS 5
SYSMAN 136
XDB 2
SYS 2885
WMSYS 112
..... (some element removed)

LBACSYS 57
25 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 651175835

------------------------------------------------------------------
Id Operation Name Rows Bytes Cost (%CPU) Time
------------------------------------------------------------------
0 SELECT STATEMENT 69320 1895K 195 (6) 00:00:03
1 HASH GROUP BY 69320 1895K 195 (6) 00:00:03
2 VIEW DBA_OBJECTS 69320 1895K 192 (4) 00:00:03
3 UNION-ALL
* 4 FILTER
* 5 HASH JOIN 85274 7744K 191 (4) 00:00:03
6 TABLE ACCESS FULL USER$ 86 1290 3 (0) 00:00:01
* 7 TABLE ACCESS FULL OBJ$ 85274 6495K 187 (3) 00:00:03
* 8 TABLE ACCESS BY INDEX ROWID IND$ 1 8 2 (0) 00:00:01
* 9 INDEX UNIQUE SCAN I_IND1 1 1 (0) 00:00:01
* 10 TABLE ACCESS BY INDEX ROWID SUM$ 1 26 0 (0) 00:00:01
* 11 INDEX UNIQUE SCAN I_SUM$_1 1 0 (0) 00:00:01
* 12 FILTER
13 NESTED LOOPS 1 28 1 (0) 00:00:01
14 INDEX FULL SCAN I_LINK1 1 13 0 (0) 00:00:01
15 TABLE ACCESS CLUSTER USER$ 1 15 1 (0) 00:00:01
* 16 INDEX UNIQUE SCAN I_USER# 1 0 (0) 00:00:01
------------------------------------------------------------------

Predicate Information (identified by operation id):
--------------------------------------------------
4 - filter(("O"."TYPE#"<>1 AND "O"."TYPE#"<>10 OR "O"."TYPE#"=1 AND (SELECT 1 FROM "SYS"."IND$" "I" WHERE "I"."OBJ#"=:B1 AND ("I"."TYPE#"=1 OR "I"."TYPE#"=2 OR
"I"."TYPE#"=3 OR "I"."TYPE#"=4 OR "I"."TYPE#"=6 OR "I"."TYPE#"=7 OR "I"."TYPE#"=9))=1)
AND DECODE("O"."TYPE#",0,'NEXT OBJECT',1,'INDEX',2,'TABLE',3,'CLUSTER',4,'VIEW',5,'SYNON YM',6,'SEQUENCE',7,'PROCEDURE',8,'FUNCTION',9,'PACKAGE',11,'PACKAGE BODY',12,'TRIGGER',13,'TYPE',14,'TYPE BODY',19,'TABLE PARTITION',20,'INDEX
PARTITION',21,'LOB',22,'LIBRARY',23,'DIRECTORY',24,'QUEUE',28,'JAVA SOURCE',29,'JAVA CLASS',30,'JAVA RESOURCE',32,'INDEXTYPE',33,'OPERATOR',34,'TABLE
SUBPARTITION',35,'INDEX SUBPARTITION',40,'LOB PARTITION',41,'LOB SUBPARTITION',42,NVL(
(SELECT DISTINCT 'REWRITE EQUIVALENCE' FROM SYS."SUM$" "S" WHERE "S"."OBJ#"=:B2 AND
BITAND("S"."XPFLAGS",8388608)=8388608),'MATERIALIZED
VIEW'),43,'DIMENSION',44,'CONTEXT',46,'RULE SET',47,'RESOURCE PLAN',48,'CONSUMER
GROUP',51,'SUBSCRIPTION',52,'LOCATION',55,'XML SCHEMA',56,'JAVA DATA',57,'SECURITY
PROFILE',59,'RULE',60,'CAPTURE',61,'APPLY',62,'EVALUATION
CONTEXT',66,'JOB',67,'PROGRAM',68,'JOB CLASS',69,'WINDOW',72,'WINDOW
GROUP',74,'SCHEDULE',79,'CHAIN',81,'FILE GROUP','UNDEFINED')='VIEW')
5 - access("O"."OWNER#"="U"."USER#")
7 - filter(BITAND("O"."FLAGS",128)=0 AND "O"."NAME"<>'_NEXT_OBJECT' AND
"O"."NAME"<>'_default_auditing_options_' AND "O"."LINKNAME" IS NULL)
8 - filter("I"."TYPE#"=1 OR "I"."TYPE#"=2 OR "I"."TYPE#"=3 OR "I"."TYPE#"=4 OR
"I"."TYPE#"=6 OR "I"."TYPE#"=7 OR "I"."TYPE#"=9)
9 - access("I"."OBJ#"=:B1)
10 - filter(BITAND("S"."XPFLAGS",8388608)=8388608)
11 - access("S"."OBJ#"=:B1)
12 - filter(NULL IS NOT NULL)
16 - access("L"."OWNER#"="U"."USER#")


Statistics
----------------------------------------------------------
8 recursive calls
0 db block gets
31053 consistent gets
2039 physical reads
0 redo size
955 bytes sent via SQL*Net to client
406 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
25 rows processed

After changing "_gby_hash_aggregation_enabled" parameter :

SQL> alter system set "_gby_hash_aggregation_enabled" = FALSE scope=both;
System altered.

SQL> select owner,count(1) from dba_objects where object_type='VIEW' group by owner;
OWNER COUNT(1)
------------------------------ ----------
CTXSYS 54
DBSNMP 1
DMSYS 1
EXFSYS 56
LBACSYS 57
MDSYS 59
ORDSYS 5
SYS 2885
SYSMAN 136
SYSTEM 12
WKSYS 79
WK_TEST 6
WMSYS 112
..... (some element removed)
XDB 2
25 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 3063327986

------------------------------------------------------------------
Id Operation Name Rows Bytes Cost (%CPU) Time
------------------------------------------------------------------
0 SELECT STATEMENT 69320 1895K 195 (6) 00:00:03
1 SORT GROUP BY 69320 1895K 195 (6) 00:00:03
2 VIEW DBA_OBJECTS 69320 1895K 192 (4) 00:00:03
3 UNION-ALL
* 4 FILTER
* 5 HASH JOIN 85274 7744K 191 (4) 00:00:03
6 TABLE ACCESS FULL USER$ 86 1290 3 (0) 00:00:01
* 7 TABLE ACCESS FULL OBJ$ 85274 6495K 187 (3) 00:00:03
* 8 TABLE ACCESS BY INDEX ROWID IND$ 1 8 2 (0) 00:00:01
* 9 INDEX UNIQUE SCAN I_IND1 1 1 (0) 00:00:01
* 10 TABLE ACCESS BY INDEX ROWID SUM$ 1 26 0 (0) 00:00:01
* 11 INDEX UNIQUE SCAN I_SUM$_1 1 0 (0) 00:00:01
* 12 FILTER
13 NESTED LOOPS 1 28 1 (0) 00:00:01
14 INDEX FULL SCAN I_LINK1 1 13 0 (0) 00:00:01
15 TABLE ACCESS CLUSTER USER$ 1 15 1 (0) 00:00:01
* 16 INDEX UNIQUE SCAN I_USER# 1 0 (0) 00:00:01
------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
4 - filter(("O"."TYPE#"<>1 AND "O"."TYPE#"<>10 OR "O"."TYPE#"=1 AND (SELECT 1 FROM
"SYS"."IND$" "I" WHERE "I"."OBJ#"=:B1 AND ("I"."TYPE#"=1 OR "I"."TYPE#"=2 OR
"I"."TYPE#"=3 OR "I"."TYPE#"=4 OR "I"."TYPE#"=6 OR "I"."TYPE#"=7 OR "I"."TYPE#"=9))=1)
AND DECODE("O"."TYPE#",0,'NEXT OBJECT',1,'INDEX',2,'TABLE',3,'CLUSTER',4,'VIEW',5,'SYNON
YM',6,'SEQUENCE',7,'PROCEDURE',8,'FUNCTION',9,'PACKAGE',11,'PACKAGE BODY',12,'TRIGGER',13,'TYPE',14,'TYPE BODY',19,'TABLE PARTITION',20,'INDEX
PARTITION',21,'LOB',22,'LIBRARY',23,'DIRECTORY',24,'QUEUE',28,'JAVA SOURCE',29,'JAVA
CLASS',30,'JAVA RESOURCE',32,'INDEXTYPE',33,'OPERATOR',34,'TABLE
SUBPARTITION',35,'INDEX SUBPARTITION',40,'LOB PARTITION',41,'LOB SUBPARTITION',42,NVL(
(SELECT DISTINCT 'REWRITE EQUIVALENCE' FROM SYS."SUM$" "S" WHERE "S"."OBJ#"=:B2 AND
BITAND("S"."XPFLAGS",8388608)=8388608),'MATERIALIZED
VIEW'),43,'DIMENSION',44,'CONTEXT',46,'RULE SET',47,'RESOURCE PLAN',48,'CONSUMER
GROUP',51,'SUBSCRIPTION',52,'LOCATION',55,'XML SCHEMA',56,'JAVA DATA',57,'SECURITY
PROFILE',59,'RULE',60,'CAPTURE',61,'APPLY',62,'EVALUATION
CONTEXT',66,'JOB',67,'PROGRAM',68,'JOB CLASS',69,'WINDOW',72,'WINDOW
GROUP',74,'SCHEDULE',79,'CHAIN',81,'FILE GROUP','UNDEFINED')='VIEW'
5 - access("O"."OWNER#"="U"."USER#")
7 - filter(BITAND("O"."FLAGS",128)=0 AND "O"."NAME"<>'_NEXT_OBJECT' AND
"O"."NAME"<>'_default_auditing_options_' AND "O"."LINKNAME" IS NULL)
8 - filter("I"."TYPE#"=1 OR "I"."TYPE#"=2 OR "I"."TYPE#"=3 OR "I"."TYPE#"=4 OR
"I"."TYPE#"=6 OR "I"."TYPE#"=7 OR "I"."TYPE#"=9)
9 - access("I"."OBJ#"=:B1)
10 - filter(BITAND("S"."XPFLAGS",8388608)=8388608)
11 - access("S"."OBJ#"=:B1)
12 - filter(NULL IS NOT NULL)
16 - access("L"."OWNER#"="U"."USER#")

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
31051 consistent gets
0 physical reads
0 redo size
949 bytes sent via SQL*Net to client
406 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
25 rows processed


We checked our affected screens in the system, and all of them are doing fine!!!!