Recently I faced an issue
where Oracle fetched wrong number of rows and seems to be a potential problem.
Issue: Wrong number
of rows returned when array size is less; and continued till array size of
98/99 <in some cases not for below> from 100 onwards result seems fine; I
believe this can be potential issue for any query though i am not sure if it is reproducible all
the time.
Test Case:
Oracle Version: 12.1.0.1/2
Here is the test case:
Created 3 tables.
create
table test_rowset1(x number,y number);
create
table test_rowset2(x number,y number);
create
table test_rowset3(x number,y number);
Inserted 1000 rows in
each and kept same values.
declare
begin
for i in
1..1000 loop
insert
into test_rowset1 values (i,1+1);
insert
into test_rowset2 values (i,1+1);
insert
into test_rowset3 values (i,1+1);
end
loop;
end;
/
commit;
Gathered stats:
exec
DBMS_STATS.GATHER_TABLE_STATS ( ownname=>'SCHE', tabname=>'TEST_ROWSET1',
METHOD_OPT =>'FOR ALL COLUMNS SIZE 1',
granularity=>'DEFAULT',cascade=>TRUE, degree=>8, estimate_percent
=> 10);
exec
DBMS_STATS.GATHER_TABLE_STATS ( ownname=>'SCHE', tabname=>'TEST_ROWSET2',
METHOD_OPT =>'FOR ALL COLUMNS SIZE 1',
granularity=>'DEFAULT',cascade=>TRUE, degree=>8, estimate_percent
=> 10);
exec
DBMS_STATS.GATHER_TABLE_STATS ( ownname=>'SCHE', tabname=>'TEST_ROWSET3',
METHOD_OPT =>'FOR ALL COLUMNS SIZE 1',
granularity=>'DEFAULT',cascade=>TRUE, degree=>8, estimate_percent
=> 10);
Here I set array size
very minimal; default is 15
Executed below query and
as per output it is expected to get only 1000 rows but here it was more.
set
autotrace on;
set
array 1;
select
/*+ leading(a,b) use_nl(c) */ a.x,a.y from test_rowset1 a,test_rowset2
b,test_rowset3 c
where
a.x=b.x
and
b.x=c.x;
1001
rows selected.------------à wrong result as only 1000 rows were expected
Elapsed: 00:00:00.28
Execution Plan
----------------------------------------------------------
Plan hash value:
3288938947
------------------------------------------------------------------------------------
| Id | Operation
| Name | Rows
| Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | SELECT
STATEMENT | |
82 | 4264 | 20 (0)| 00:00:01 |
| 1 |
NESTED LOOPS |
| 82 | 4264 | 20
(0)| 00:00:01 |
|* 2 |
HASH JOIN |
| 82 | 3198 | 4
(0)| 00:00:01 |
| 3 |
TABLE ACCESS FULL| TEST_ROWSET1 | 82 | 2132 |
2 (0)| 00:00:01 |
| 4 |
TABLE ACCESS FULL| TEST_ROWSET2 | 82 | 1066 |
2 (0)| 00:00:01 |
|* 5 |
TABLE ACCESS FULL | TEST_ROWSET3 | 1 | 13 |
0 (0)| 00:00:01 |
------------------------------------------------------------------------------------
Predicate Information
(identified by operation id):
---------------------------------------------------
2 -
access("A"."X"="B"."X")
5 -
filter("B"."X"="C"."X")
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
8013 consistent gets
0 physical reads
0 redo size
36890 bytes sent via SQL*Net to client
3888 bytes received via SQL*Net from client
502 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1001 rows processed-----Wrong no of rows processed
Column Projection
Information (identified by operation id):
-----------------------------------------------------------
1 - "A"."X"[NUMBER,22],
"A"."Y"[NUMBER,22]
2 -
(#keys=1) "A"."X"[NUMBER,22],
"B"."X"[NUMBER,22], "A"."Y"[NUMBER,22]
3
- (rowset=200) "A"."X"[NUMBER,22],
"A"."Y"[NUMBER,22]
4
- (rowset=200) "B"."X"[NUMBER,22]
See above rowset
optimization is used and this sounds new in 12 C;
Next I executed with
array size as 5000 that is max and after setting this value query fetched
correct no of rows.
Sql> Set array 5000
1000
rows selected.----Correct no rows returned.
Elapsed: 00:00:00.08
Execution Plan
----------------------------------------------------------
Plan hash value:
3288938947
------------------------------------------------------------------------------------
| Id | Operation
| Name | Rows
| Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | SELECT
STATEMENT | |
82 | 4264 | 20 (0)| 00:00:01 |
| 1 |
NESTED LOOPS |
| 82 | 4264 | 20
(0)| 00:00:01 |
|* 2 |
HASH JOIN |
| 82 | 3198 | 4
(0)| 00:00:01 |
| 3 |
TABLE ACCESS FULL| TEST_ROWSET1 | 82 | 2132 |
2 (0)| 00:00:01 |
| 4 |
TABLE ACCESS FULL| TEST_ROWSET2 | 82 | 1066 |
2 (0)| 00:00:01 |
|* 5 |
TABLE ACCESS FULL | TEST_ROWSET3 | 1 | 13 |
0 (0)| 00:00:01 |
------------------------------------------------------------------------------------
Predicate Information
(identified by operation id):
---------------------------------------------------
2 -
access("A"."X"="B"."X")
5 -
filter("B"."X"="C"."X")
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
7016 consistent gets
0 physical reads
0 redo size
9150 bytes sent via SQL*Net to client
389 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1000 rows processed------Correct.
This arraysize is quite important for queries
especially the big one the extract one’s. Even JDBC module queries can get
affected due to this.
Now in 12C there is a workaround to suppress
the issue and is to set _rowsets_enabled=false which is TRUE by default
Seem an optimization step in 12C
NAME
VALUE
DEFLT TYPE
--------------------
-------------------- --------- --------------------
_rowsets_enabled
TRUE
TRUE boolean
Executed same query with array size 1 and set
hidden parameter as false.
Set array 1;
Alter
session set "_rowsets_enabled"=false;
Session altered.
Execution Plan
----------------------------------------------------------
Plan hash value:
3288938947
------------------------------------------------------------------------------------
| Id | Operation
| Name | Rows
| Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | SELECT
STATEMENT | |
82 | 4264 | 20 (0)| 00:00:01 |
| 1 |
NESTED LOOPS |
| 82 | 4264 | 20
(0)| 00:00:01 |
|* 2 |
HASH JOIN |
| 82 | 3198 | 4
(0)| 00:00:01 |
| 3 |
TABLE ACCESS FULL| TEST_ROWSET1 | 82 | 2132 |
2 (0)| 00:00:01 |
| 4 |
TABLE ACCESS FULL| TEST_ROWSET2 | 82 | 1066 |
2 (0)| 00:00:01 |
|* 5 |
TABLE ACCESS FULL | TEST_ROWSET3 | 1 | 13 |
0 (0)| 00:00:01 |
------------------------------------------------------------------------------------
Predicate Information
(identified by operation id):
---------------------------------------------------
2 -
access("A"."X"="B"."X")
5 -
filter("B"."X"="C"."X")
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
7148 consistent gets
0 physical reads
0 redo size
12200 bytes sent via SQL*Net to client
850 bytes received via SQL*Net from client
68 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1000 rows processed-----------à Correct no of rows fetched.
After suppressing rowset info; can see below
no rowset info.
Column Projection
Information (identified by operation id):
-----------------------------------------------------------
1 -
"A"."X"[NUMBER,22], "A"."Y"[NUMBER,22]
2 -
(#keys=1) "A"."X"[NUMBER,22],
"B"."X"[NUMBER,22], "A"."Y"[NUMBER,22]
3 -
"A"."X"[NUMBER,22], "A"."Y"[NUMBER,22]
4 -
"B"."X"[NUMBER,22]
Hope you enjoyed this edition.
Enjoy Learning!!!!
13 comments:
cool
As Always very detailed and informative !!
I would like to appreciate your work for good accuracy and got informative knowledge from here.
http://www.erptree.com/course/oracle-fusion-procurement-online-training/
nice informative blog, thanks for this post.
Oracle institute in Noida
Thanks for stopping by and I am glad that you liked the article.
Thanks for sharing a useful information.. we have learnt so much information from your blog..... keep sharing
Workday HCM Online Training
Oracle Fusion Financials Online Training
Oracle Fusion HCM Online Training
Oracle Fusion SCM Online Training
Excellent blog I visit this blog it's really awesome. The important thing is that in this blog content written clearly and understandable. The content of information is very informative. Thanks for the excellent and great idea. keep blogging
Oracle Fusion Financials Online Training
Oracle Fusion HCM Online Training
Oracle Fusion SCM Online Training
Your good knowledge and kindness in playing with all the pieces were very useful. I don’t know what I would have done if I had not encountered such a step like this.
Artificial Intelligence Online Training
Java Online Training
AWS Online Training
Machine Learning Online Training
Data Science Online Training
DevOps Online Training
I have been reading for the past two days about your blogs and topics, still on fetching! Wondering about your words on each line was massively effective. Techno-based information has been fetched in each of your topics. Sure it will enhance and fill the queries of the public needs. Feeling so glad about your article. Thanks…!
https://www.analyticspath.com/datascience-corporate-training
Data Science Corporate Training
Thanks for sharing this great information I am impressed by the information that you have on this blog. Same as your blog i found another one Oracle Fusion HCM . Actually, I was looking for the same information on internet for
Oracle Fusion HCM Interview Questions and Answers and came across your blog. I am impressed by the information that you have on this blog. It shows how well you understand this subject.
Thanks for your information. very good article.
Learn Devops Online
Devops Online Training in Hyderabad
Thank you for sharing wonderful information with us to get some idea about that content.
Python Online Training in India
Python Online Training In Hyderabad
Post a Comment