SlideShare una empresa de Scribd logo
1 de 8
Subquery Factoring
Oracle introduce WITH clause in the query starting from Oracle 9i. In few articles that I found while googling,
we can use this WITH clause to write subquery factoring or recursive query.
In this chance, I would like to show you the benefit of “Subquery Factoring” against Full Table Scan and also we
can see the same method against Unique Index Scan.
For the first case, I would like to show the comparison between the traditional and subquery factoring methods
for Full Table Scan operation and for the second case; for Unique Index Scan. The objective is to see the
reduction in LIO and PIO for MINUS operation which use FTS.
Subquery Factoring for FTS
Original Query
SQL>
2
3
4
5

select /*+ parallel(a,8) */ subscriber_no from subscriber a
where sub_status = 'A'
minus
select /*+ parallel(a,8) */ subscriber_no from subscriber a
where sub_status = 'C';

41220406 rows selected.
Elapsed: 00:04:14.03
Execution Plan
--------------------------------------------------------------------------------------------------------------------------------------------------------------------| Id | Operation
| Name
| Rows | Bytes |TempSpc| Cost |
TQ |IN-OUT| PQ Distrib |
-----------------------------------------------------------------------------------------------------------|
0 | SELECT STATEMENT
|
|
34M|
596M|
| 99966 |
|
|
|
|
1 | PX COORDINATOR
|
|
|
|
|
|
|
|
|
|
2 |
PX SEND QC (RANDOM)
| :TQ10002
|
|
|
|
| Q1,02 | P->S | QC (RAND) |
|
3 |
MINUS
|
|
|
|
|
| Q1,02 | PCWP |
|
|
4 |
SORT UNIQUE
|
|
34M|
298M|
665M| 49983 | Q1,02 | PCWP |
|
|
5 |
PX RECEIVE
|
|
34M|
298M|
| 34566 | Q1,02 | PCWP |
|
|
6 |
PX SEND HASH
| :TQ10000
|
34M|
298M|
| 34566 | Q1,00 | P->P | HASH
|
|
7 |
PX BLOCK ITERATOR |
|
34M|
298M|
| 34566 | Q1,00 | PCWC |
|
|* 8 |
TABLE ACCESS FULL| SUBSCRIBER |
34M|
298M|
| 34566 | Q1,00 | PCWP |
|
|
9 |
SORT UNIQUE
|
|
34M|
298M|
665M| 49983 | Q1,02 | PCWP |
|
| 10 |
PX RECEIVE
|
|
34M|
298M|
| 34566 | Q1,02 | PCWP |
|
| 11 |
PX SEND HASH
| :TQ10001
|
34M|
298M|
| 34566 | Q1,01 | P->P | HASH
|
| 12 |
PX BLOCK ITERATOR |
|
34M|
298M|
| 34566 | Q1,01 | PCWC |
|
|* 13 |
TABLE ACCESS FULL| SUBSCRIBER |
34M|
298M|
| 34566 | Q1,01 | PCWP |
|
------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
--------------------------------------------------8 - filter("SUB_STATUS"='A')
13 - filter("SUB_STATUS"='C')
Note
----- cpu costing is off (consider enabling it)
Statistics
---------------------------------------------------------1258 recursive calls
140 db block gets
2303047 consistent gets
2353434 physical reads
632 redo size
799460311 bytes sent via SQL*Net to client
30228789 bytes received via SQL*Net from client
2748029 SQL*Net roundtrips to/from client
16 sorts (memory)
8 sorts (disk)
41220406 rows processed
SubQuery Factoring
SQL>
2
3
4
5
6
7
8
9
10
11
12
13
14

with qry as
(
select /*+ parallel(a,8) */ subscriber_no,
case
when sub_status = 'A' then 1
when sub_status = 'C' then 2
else 0
end as ss
from subscriber a
where sub_status in ('A', 'C')
)
select subscriber_no from qry where ss = 1
minus
select subscriber_no from qry where ss = 2;

41220406 rows selected.
Elapsed: 00:04:20.10
Execution Plan
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| Id | Operation
| Name
| Rows | Bytes |TempSpc| Cost |
TQ |IN-OUT| PQ Distrib |
------------------------------------------------------------------------------------------------------------------------------|
0 | SELECT STATEMENT
|
|
69M| 2122M|
| 87770 |
|
|
|
|
1 | TEMP TABLE TRANSFORMATION |
|
|
|
|
|
|
|
|
|
2 |
PX COORDINATOR
|
|
|
|
|
|
|
|
|
|
3 |
PX SEND QC (RANDOM)
| :TQ10001
|
69M|
596M|
| 34566 | Q1,01 | P->S | QC (RAND) |
|
4 |
LOAD AS SELECT
|
|
|
|
|
| Q1,01 | PCWP |
|
|
5 |
PX RECEIVE
|
|
69M|
596M|
| 34566 | Q1,01 | PCWP |
|
|
6 |
PX SEND ROUND-ROBIN | :TQ10000
|
69M|
596M|
| 34566 | Q1,00 | P->P | RND-ROBIN |
|
7 |
PX BLOCK ITERATOR
|
|
69M|
596M|
| 34566 | Q1,00 | PCWC |
|
|* 8 |
TABLE ACCESS FULL | SUBSCRIBER
|
69M|
596M|
| 34566 | Q1,00 | PCWP |
|
|
9 |
PX COORDINATOR
|
|
|
|
|
|
|
|
|
| 10 |
PX SEND QC (RANDOM)
| :TQ20002
|
|
|
|
| Q2,02 | P->S | QC (RAND) |
| 11 |
MINUS
|
|
|
|
|
| Q2,02 | PCWP |
|
| 12 |
SORT UNIQUE
|
|
69M| 1061M| 1598M| 43885 | Q2,02 | PCWP |
|
| 13 |
PX RECEIVE
|
|
69M| 1061M|
|
719 | Q2,02 | PCWP |
|
| 14 |
PX SEND HASH
| :TQ20000
|
69M| 1061M|
|
719 | Q2,00 | P->P | HASH
|
|* 15 |
VIEW
|
|
69M| 1061M|
|
719 | Q2,00 | PCWP |
|
| 16 |
PX BLOCK ITERATOR |
|
69M|
596M|
|
719 | Q2,00 | PCWC |
|
| 17 |
TABLE ACCESS FULL| SYS_TEMP_0FD9D6611_C3DD254C |
69M|
596M|
|
719 | Q2,00 | PCWP |
|
| 18 |
SORT UNIQUE
|
|
69M| 1061M| 1598M| 43885 | Q2,02 | PCWP |
|
| 19 |
PX RECEIVE
|
|
69M| 1061M|
|
719 | Q2,02 | PCWP |
|
| 20 |
PX SEND HASH
| :TQ20001
|
69M| 1061M|
|
719 | Q2,01 | P->P | HASH
|
|* 21 |
VIEW
|
|
69M| 1061M|
|
719 | Q2,01 | PCWP |
|
| 22 |
PX BLOCK ITERATOR |
|
69M|
596M|
|
719 | Q2,01 | PCWC |
|
| 23 |
TABLE ACCESS FULL| SYS_TEMP_0FD9D6611_C3DD254C |
69M|
596M|
|
719 | Q2,01 | PCWP |
|
-------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
--------------------------------------------------8 - filter("SUB_STATUS"='A' OR "SUB_STATUS"='C')
15 - filter("SS"=1)
21 - filter("SS"=0)
Note
----- cpu costing is off (consider enabling it)
Statistics
---------------------------------------------------------2511 recursive calls
83554 db block gets
1316155 consistent gets
1368259 physical reads
304360 redo size
799460311
30228789
2748029
28
8
41220406

bytes sent via SQL*Net to client
bytes received via SQL*Net from client
SQL*Net roundtrips to/from client
sorts (memory)
sorts (disk)
rows processed

Please see the highlighted parts, the PIO and LIO reduced by 100% (half) when we use subquery factoring. It
can be happened because Oracle scans SUBSCRIBER only once and keeps the result in the memory and it will
be reused for second, third operation and so on. If we see more in the execution plan, there is increment in the
TEMP space usage, because when needed, Oracle will spill the information/data from the buffer cache into the
Temporary Tablespace. This is acceptable if there is enough space on the Temporary Tablespace and also fast
enough disk. Due to this “temporary” operation, Oracle produce more redo information (approx.. 300kB in this
test case)
Subquery Factoring for Index Unique Scan
Original Query
SQL>
2
3
4
5

select subscriber_no from tksappo.subscriber
where subscriber_no = 7266421
minus
select subscriber_no from tksappo.subscriber
where subscriber_no = 6566380;

Elapsed: 00:00:00.06
Execution Plan
----------------------------------------------------------------------------------------------------------------------------| Id | Operation
| Name
| Rows | Bytes | Cost |
-------------------------------------------------------------------|
0 | SELECT STATEMENT
|
|
1 |
14 |
78 |
|
1 | MINUS
|
|
|
|
|
|* 2 |
INDEX UNIQUE SCAN| SUBSCRIBER_PK |
1 |
7 |
1 |
|* 3 |
INDEX UNIQUE SCAN| SUBSCRIBER_PK |
1 |
7 |
1 |
-------------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------2 - access("SUBSCRIBER_NO"=7266421)
3 - access("SUBSCRIBER_NO"=6566380)
Note
----- cpu costing is off (consider enabling it)
Statistics
---------------------------------------------------------565 recursive calls
0 db block gets
138 consistent gets
26 physical reads
0 redo size
523 bytes sent via SQL*Net to client
492 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
6 sorts (memory)
0 sorts (disk)
1 rows processed
SubQuery Factoring
SQL>
2
3
4
5
6
7
8
9
10
11
12
13
14

with qry as
(
select subscriber_no,
case
when subscriber_no = 7266421 then 1
when subscriber_no = 6566380 then 2
else 0
end as ss
from tksappo.subscriber
where subscriber_no in (7266421, 6566380)
)
select subscriber_no from qry where ss = 1
minus
select subscriber_no from qry where ss = 2;

Elapsed: 00:00:00.03
Execution Plan
--------------------------------------------------------------------------------------------------------------------------------------------------| Id | Operation
| Name
| Rows | Bytes | Cost |
-----------------------------------------------------------------------------------------|
0 | SELECT STATEMENT
|
|
2 |
64 |
80 |
|
1 | TEMP TABLE TRANSFORMATION |
|
|
|
|
|
2 |
LOAD AS SELECT
|
|
|
|
|
|
3 |
INLIST ITERATOR
|
|
|
|
|
|* 4 |
INDEX UNIQUE SCAN
| SUBSCRIBER_PK
|
2 |
14 |
1 |
|
5 |
MINUS
|
|
|
|
|
|
6 |
SORT UNIQUE
|
|
2 |
32 |
40 |
|* 7 |
VIEW
|
|
2 |
32 |
2 |
|
8 |
TABLE ACCESS FULL
| SYS_TEMP_0FD9D6613_C3DD254C |
2 |
14 |
2 |
|
9 |
SORT UNIQUE
|
|
2 |
32 |
40 |
|* 10 |
VIEW
|
|
2 |
32 |
2 |
| 11 |
TABLE ACCESS FULL
| SYS_TEMP_0FD9D6613_C3DD254C |
2 |
14 |
2 |
-----------------------------------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------4 - access("SUBSCRIBER_NO"=6566380 OR "SUBSCRIBER_NO"=7266421)
7 - filter("SS"=1)
10 - filter("SS"=0)
Note
----- cpu costing is off (consider enabling it)
Statistics
---------------------------------------------------------1151 recursive calls
12 db block gets
342 consistent gets
68 physical reads
1568 redo size
523 bytes sent via SQL*Net to client
492 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
19 sorts (memory)
0 sorts (disk)
1 rows processed
We have different result when we use Unique Index Scan. There is an increment in LIO and PIO. So far what I
can see in this increment is due to:
- Temporary table creation (we don’t have it in the original method)
Conclusion
1. Subquery factoring is good to simplify query (more readable) and it can give significant improvement
when we are working with FTS and scan the same object over and over again.
2. There is no silver bullet in SQL tuning until unless we did some test to confirm it. In this example, FTS
and Index Scan gives different result when we rewrite the SQL using WITH clause.
3. Different version of Oracle will produce different result, all above scenarios were tested on Oracle
10.2.0.5 (PET CM database)

Más contenido relacionado

Destacado (7)

Correlated update vs merge
Correlated update vs mergeCorrelated update vs merge
Correlated update vs merge
 
Checking clustering factor to detect row migration
Checking clustering factor to detect row migrationChecking clustering factor to detect row migration
Checking clustering factor to detect row migration
 
Not in vs not exists
Not in vs not existsNot in vs not exists
Not in vs not exists
 
Hash join
Hash joinHash join
Hash join
 
Nested loop join technique - part2
Nested loop join technique - part2Nested loop join technique - part2
Nested loop join technique - part2
 
Few useful features
Few useful featuresFew useful features
Few useful features
 
Introduction to oracle optimizer
Introduction to oracle optimizerIntroduction to oracle optimizer
Introduction to oracle optimizer
 

Similar a Subquery factoring for FTS

Oracle Basics and Architecture
Oracle Basics and ArchitectureOracle Basics and Architecture
Oracle Basics and Architecture
Sidney Chen
 
Adaptive Query Optimization in 12c
Adaptive Query Optimization in 12cAdaptive Query Optimization in 12c
Adaptive Query Optimization in 12c
Anju Garg
 
Sydney Oracle Meetup - access paths
Sydney Oracle Meetup - access pathsSydney Oracle Meetup - access paths
Sydney Oracle Meetup - access paths
paulguerin
 
Writing efficient sql
Writing efficient sqlWriting efficient sql
Writing efficient sql
j9soto
 

Similar a Subquery factoring for FTS (20)

Analysing and troubleshooting Parallel Execution IT Tage 2015
Analysing and troubleshooting Parallel Execution IT Tage 2015Analysing and troubleshooting Parallel Execution IT Tage 2015
Analysing and troubleshooting Parallel Execution IT Tage 2015
 
Dbms plan - A swiss army knife for performance engineers
Dbms plan - A swiss army knife for performance engineersDbms plan - A swiss army knife for performance engineers
Dbms plan - A swiss army knife for performance engineers
 
Parallel Execution With Oracle Database 12c - Masterclass
Parallel Execution With Oracle Database 12c - MasterclassParallel Execution With Oracle Database 12c - Masterclass
Parallel Execution With Oracle Database 12c - Masterclass
 
Randolf Geist – IT-Tage 2015 – Oracle Parallel Execution – Analyse und Troubl...
Randolf Geist – IT-Tage 2015 – Oracle Parallel Execution – Analyse und Troubl...Randolf Geist – IT-Tage 2015 – Oracle Parallel Execution – Analyse und Troubl...
Randolf Geist – IT-Tage 2015 – Oracle Parallel Execution – Analyse und Troubl...
 
Hash joins and bloom filters at AMIS25
Hash joins and bloom filters at AMIS25Hash joins and bloom filters at AMIS25
Hash joins and bloom filters at AMIS25
 
Top 10 tips for Oracle performance
Top 10 tips for Oracle performanceTop 10 tips for Oracle performance
Top 10 tips for Oracle performance
 
OracleDatabase12cPXNewFeatures_ITOUG_2018.pdf
OracleDatabase12cPXNewFeatures_ITOUG_2018.pdfOracleDatabase12cPXNewFeatures_ITOUG_2018.pdf
OracleDatabase12cPXNewFeatures_ITOUG_2018.pdf
 
Embarcadero In Search of Plan Stability Part 1 Webinar Slides
Embarcadero In Search of Plan Stability Part 1 Webinar SlidesEmbarcadero In Search of Plan Stability Part 1 Webinar Slides
Embarcadero In Search of Plan Stability Part 1 Webinar Slides
 
Oracle Basics and Architecture
Oracle Basics and ArchitectureOracle Basics and Architecture
Oracle Basics and Architecture
 
Informix Warehouse Accelerator (IWA) features in version 12.1
Informix Warehouse Accelerator (IWA) features in version 12.1Informix Warehouse Accelerator (IWA) features in version 12.1
Informix Warehouse Accelerator (IWA) features in version 12.1
 
Deep review of LMS process
Deep review of LMS processDeep review of LMS process
Deep review of LMS process
 
Adaptive Query Optimization in 12c
Adaptive Query Optimization in 12cAdaptive Query Optimization in 12c
Adaptive Query Optimization in 12c
 
Oracle Parallel Distribution and 12c Adaptive Plans
Oracle Parallel Distribution and 12c Adaptive PlansOracle Parallel Distribution and 12c Adaptive Plans
Oracle Parallel Distribution and 12c Adaptive Plans
 
Px execution in rac
Px execution in racPx execution in rac
Px execution in rac
 
Sydney Oracle Meetup - access paths
Sydney Oracle Meetup - access pathsSydney Oracle Meetup - access paths
Sydney Oracle Meetup - access paths
 
Christo Kutrovsky - Maximize Data Warehouse Performance with Parallel Queries
Christo Kutrovsky - Maximize Data Warehouse Performance with Parallel QueriesChristo Kutrovsky - Maximize Data Warehouse Performance with Parallel Queries
Christo Kutrovsky - Maximize Data Warehouse Performance with Parallel Queries
 
Oracle 11g caracteristicas poco documentadas 3 en 1
Oracle 11g caracteristicas poco documentadas 3 en 1Oracle 11g caracteristicas poco documentadas 3 en 1
Oracle 11g caracteristicas poco documentadas 3 en 1
 
UKOUG 2019 - SQL features
UKOUG 2019 - SQL featuresUKOUG 2019 - SQL features
UKOUG 2019 - SQL features
 
Evolution of Performance Management: Oracle 12c adaptive optimizations - ukou...
Evolution of Performance Management: Oracle 12c adaptive optimizations - ukou...Evolution of Performance Management: Oracle 12c adaptive optimizations - ukou...
Evolution of Performance Management: Oracle 12c adaptive optimizations - ukou...
 
Writing efficient sql
Writing efficient sqlWriting efficient sql
Writing efficient sql
 

Último

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 

Último (20)

Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 

Subquery factoring for FTS

  • 1. Subquery Factoring Oracle introduce WITH clause in the query starting from Oracle 9i. In few articles that I found while googling, we can use this WITH clause to write subquery factoring or recursive query. In this chance, I would like to show you the benefit of “Subquery Factoring” against Full Table Scan and also we can see the same method against Unique Index Scan. For the first case, I would like to show the comparison between the traditional and subquery factoring methods for Full Table Scan operation and for the second case; for Unique Index Scan. The objective is to see the reduction in LIO and PIO for MINUS operation which use FTS.
  • 2. Subquery Factoring for FTS Original Query SQL> 2 3 4 5 select /*+ parallel(a,8) */ subscriber_no from subscriber a where sub_status = 'A' minus select /*+ parallel(a,8) */ subscriber_no from subscriber a where sub_status = 'C'; 41220406 rows selected. Elapsed: 00:04:14.03 Execution Plan --------------------------------------------------------------------------------------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes |TempSpc| Cost | TQ |IN-OUT| PQ Distrib | -----------------------------------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 34M| 596M| | 99966 | | | | | 1 | PX COORDINATOR | | | | | | | | | | 2 | PX SEND QC (RANDOM) | :TQ10002 | | | | | Q1,02 | P->S | QC (RAND) | | 3 | MINUS | | | | | | Q1,02 | PCWP | | | 4 | SORT UNIQUE | | 34M| 298M| 665M| 49983 | Q1,02 | PCWP | | | 5 | PX RECEIVE | | 34M| 298M| | 34566 | Q1,02 | PCWP | | | 6 | PX SEND HASH | :TQ10000 | 34M| 298M| | 34566 | Q1,00 | P->P | HASH | | 7 | PX BLOCK ITERATOR | | 34M| 298M| | 34566 | Q1,00 | PCWC | | |* 8 | TABLE ACCESS FULL| SUBSCRIBER | 34M| 298M| | 34566 | Q1,00 | PCWP | | | 9 | SORT UNIQUE | | 34M| 298M| 665M| 49983 | Q1,02 | PCWP | | | 10 | PX RECEIVE | | 34M| 298M| | 34566 | Q1,02 | PCWP | | | 11 | PX SEND HASH | :TQ10001 | 34M| 298M| | 34566 | Q1,01 | P->P | HASH | | 12 | PX BLOCK ITERATOR | | 34M| 298M| | 34566 | Q1,01 | PCWC | | |* 13 | TABLE ACCESS FULL| SUBSCRIBER | 34M| 298M| | 34566 | Q1,01 | PCWP | | ------------------------------------------------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------8 - filter("SUB_STATUS"='A') 13 - filter("SUB_STATUS"='C') Note ----- cpu costing is off (consider enabling it) Statistics ---------------------------------------------------------1258 recursive calls 140 db block gets 2303047 consistent gets 2353434 physical reads 632 redo size 799460311 bytes sent via SQL*Net to client 30228789 bytes received via SQL*Net from client 2748029 SQL*Net roundtrips to/from client 16 sorts (memory) 8 sorts (disk) 41220406 rows processed
  • 3. SubQuery Factoring SQL> 2 3 4 5 6 7 8 9 10 11 12 13 14 with qry as ( select /*+ parallel(a,8) */ subscriber_no, case when sub_status = 'A' then 1 when sub_status = 'C' then 2 else 0 end as ss from subscriber a where sub_status in ('A', 'C') ) select subscriber_no from qry where ss = 1 minus select subscriber_no from qry where ss = 2; 41220406 rows selected. Elapsed: 00:04:20.10 Execution Plan ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes |TempSpc| Cost | TQ |IN-OUT| PQ Distrib | ------------------------------------------------------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 69M| 2122M| | 87770 | | | | | 1 | TEMP TABLE TRANSFORMATION | | | | | | | | | | 2 | PX COORDINATOR | | | | | | | | | | 3 | PX SEND QC (RANDOM) | :TQ10001 | 69M| 596M| | 34566 | Q1,01 | P->S | QC (RAND) | | 4 | LOAD AS SELECT | | | | | | Q1,01 | PCWP | | | 5 | PX RECEIVE | | 69M| 596M| | 34566 | Q1,01 | PCWP | | | 6 | PX SEND ROUND-ROBIN | :TQ10000 | 69M| 596M| | 34566 | Q1,00 | P->P | RND-ROBIN | | 7 | PX BLOCK ITERATOR | | 69M| 596M| | 34566 | Q1,00 | PCWC | | |* 8 | TABLE ACCESS FULL | SUBSCRIBER | 69M| 596M| | 34566 | Q1,00 | PCWP | | | 9 | PX COORDINATOR | | | | | | | | | | 10 | PX SEND QC (RANDOM) | :TQ20002 | | | | | Q2,02 | P->S | QC (RAND) | | 11 | MINUS | | | | | | Q2,02 | PCWP | | | 12 | SORT UNIQUE | | 69M| 1061M| 1598M| 43885 | Q2,02 | PCWP | | | 13 | PX RECEIVE | | 69M| 1061M| | 719 | Q2,02 | PCWP | | | 14 | PX SEND HASH | :TQ20000 | 69M| 1061M| | 719 | Q2,00 | P->P | HASH | |* 15 | VIEW | | 69M| 1061M| | 719 | Q2,00 | PCWP | | | 16 | PX BLOCK ITERATOR | | 69M| 596M| | 719 | Q2,00 | PCWC | | | 17 | TABLE ACCESS FULL| SYS_TEMP_0FD9D6611_C3DD254C | 69M| 596M| | 719 | Q2,00 | PCWP | | | 18 | SORT UNIQUE | | 69M| 1061M| 1598M| 43885 | Q2,02 | PCWP | | | 19 | PX RECEIVE | | 69M| 1061M| | 719 | Q2,02 | PCWP | | | 20 | PX SEND HASH | :TQ20001 | 69M| 1061M| | 719 | Q2,01 | P->P | HASH | |* 21 | VIEW | | 69M| 1061M| | 719 | Q2,01 | PCWP | | | 22 | PX BLOCK ITERATOR | | 69M| 596M| | 719 | Q2,01 | PCWC | | | 23 | TABLE ACCESS FULL| SYS_TEMP_0FD9D6611_C3DD254C | 69M| 596M| | 719 | Q2,01 | PCWP | | ------------------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------8 - filter("SUB_STATUS"='A' OR "SUB_STATUS"='C') 15 - filter("SS"=1) 21 - filter("SS"=0) Note ----- cpu costing is off (consider enabling it) Statistics ---------------------------------------------------------2511 recursive calls 83554 db block gets 1316155 consistent gets 1368259 physical reads 304360 redo size
  • 4. 799460311 30228789 2748029 28 8 41220406 bytes sent via SQL*Net to client bytes received via SQL*Net from client SQL*Net roundtrips to/from client sorts (memory) sorts (disk) rows processed Please see the highlighted parts, the PIO and LIO reduced by 100% (half) when we use subquery factoring. It can be happened because Oracle scans SUBSCRIBER only once and keeps the result in the memory and it will be reused for second, third operation and so on. If we see more in the execution plan, there is increment in the TEMP space usage, because when needed, Oracle will spill the information/data from the buffer cache into the Temporary Tablespace. This is acceptable if there is enough space on the Temporary Tablespace and also fast enough disk. Due to this “temporary” operation, Oracle produce more redo information (approx.. 300kB in this test case)
  • 5. Subquery Factoring for Index Unique Scan Original Query SQL> 2 3 4 5 select subscriber_no from tksappo.subscriber where subscriber_no = 7266421 minus select subscriber_no from tksappo.subscriber where subscriber_no = 6566380; Elapsed: 00:00:00.06 Execution Plan ----------------------------------------------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost | -------------------------------------------------------------------| 0 | SELECT STATEMENT | | 1 | 14 | 78 | | 1 | MINUS | | | | | |* 2 | INDEX UNIQUE SCAN| SUBSCRIBER_PK | 1 | 7 | 1 | |* 3 | INDEX UNIQUE SCAN| SUBSCRIBER_PK | 1 | 7 | 1 | -------------------------------------------------------------------Predicate Information (identified by operation id): --------------------------------------------------2 - access("SUBSCRIBER_NO"=7266421) 3 - access("SUBSCRIBER_NO"=6566380) Note ----- cpu costing is off (consider enabling it) Statistics ---------------------------------------------------------565 recursive calls 0 db block gets 138 consistent gets 26 physical reads 0 redo size 523 bytes sent via SQL*Net to client 492 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 6 sorts (memory) 0 sorts (disk) 1 rows processed
  • 6. SubQuery Factoring SQL> 2 3 4 5 6 7 8 9 10 11 12 13 14 with qry as ( select subscriber_no, case when subscriber_no = 7266421 then 1 when subscriber_no = 6566380 then 2 else 0 end as ss from tksappo.subscriber where subscriber_no in (7266421, 6566380) ) select subscriber_no from qry where ss = 1 minus select subscriber_no from qry where ss = 2; Elapsed: 00:00:00.03 Execution Plan --------------------------------------------------------------------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost | -----------------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 2 | 64 | 80 | | 1 | TEMP TABLE TRANSFORMATION | | | | | | 2 | LOAD AS SELECT | | | | | | 3 | INLIST ITERATOR | | | | | |* 4 | INDEX UNIQUE SCAN | SUBSCRIBER_PK | 2 | 14 | 1 | | 5 | MINUS | | | | | | 6 | SORT UNIQUE | | 2 | 32 | 40 | |* 7 | VIEW | | 2 | 32 | 2 | | 8 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6613_C3DD254C | 2 | 14 | 2 | | 9 | SORT UNIQUE | | 2 | 32 | 40 | |* 10 | VIEW | | 2 | 32 | 2 | | 11 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6613_C3DD254C | 2 | 14 | 2 | -----------------------------------------------------------------------------------------Predicate Information (identified by operation id): --------------------------------------------------4 - access("SUBSCRIBER_NO"=6566380 OR "SUBSCRIBER_NO"=7266421) 7 - filter("SS"=1) 10 - filter("SS"=0) Note ----- cpu costing is off (consider enabling it) Statistics ---------------------------------------------------------1151 recursive calls 12 db block gets 342 consistent gets 68 physical reads 1568 redo size 523 bytes sent via SQL*Net to client 492 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 19 sorts (memory) 0 sorts (disk) 1 rows processed
  • 7. We have different result when we use Unique Index Scan. There is an increment in LIO and PIO. So far what I can see in this increment is due to: - Temporary table creation (we don’t have it in the original method)
  • 8. Conclusion 1. Subquery factoring is good to simplify query (more readable) and it can give significant improvement when we are working with FTS and scan the same object over and over again. 2. There is no silver bullet in SQL tuning until unless we did some test to confirm it. In this example, FTS and Index Scan gives different result when we rewrite the SQL using WITH clause. 3. Different version of Oracle will produce different result, all above scenarios were tested on Oracle 10.2.0.5 (PET CM database)