Tuesday, June 11, 2019


How to get Audit Report using CURL CMD from Oracle HCM Cloud:

Roles required:
Audit Access for Cloud Access Security Broker
Internal Auditor (Optional)
IT Auditor (Optional)

This SQL will list all the VO object that are enabled for Audit.

Select * from FND_AUDIT_WEBAPP_AM where WEBAPP = 'hcmCore';


curl -i -k --user <UserName>:<Pwd> -H "Content-Type: application/json" -X POST --data @GetAuditData.json https://<HCM Cloud Host Name>/fscmRestApi/fndAuditRESTService/audittrail/getaudithistory > OutputFileName.txt

Json File Sample content:
{
    "fromDate": "2019-01-08",
    "toDate": "2019-01-12",
    "product": "hcmCore",
    "businessObjectType": "oracle.apps.hcm.people.core.uiModel.view.ManagePersonVO",
 "includeAttributes":"false",
 "attributeDetailMode":"true",
    "includeChildObjects":"true",
 "includeImpersonator":"true",
 "timeZone":"US Pacific Time"
}

{
    "fromDate": "2018-10-10",
    "toDate": "2018-11-06",
    "product": "hcmCoreSetup",
 "businessObjectType": "oracle.apps.hcm.workStructures.grades.uiModel.view.GradeVO",
 "includeAttributes":"false",
 "attributeDetailMode":"true",
    "includeChildObjects":"true",
 "includeImpersonator":"true",
 "timeZone":"US Pacific Time"
}

curl -i -k -u <UserName>:<Pwd> -X GET https://<HCM Cloud Host Name>/hcmRestApi/scim/Users > OutputFileName.txt

 

How to fetch last run date of a BI Report in HCM Cloud.

You can do this in two ways, either get the processing start date of the previous run (you will have to modify the below Sql a little bit for this approach) or have a effective date parameter in your report and use below query to fetch the value from previous run.

SELECT TO_DATE(SUBSTR(PP.VALUE, INSTR(PP.VALUE, '"', 1, 3) + 1, 19), 'MM-DD-YYYY HH24:MI:SS')  LAST_RUN_DATE
FROM fusion_ora_ess.request_history_view rh
 ,fusion_ora_ess.request_property_view rp
 ,fusion_ora_ess.request_property_view pp
WHERE 1 = 1
 AND rp.requestid = rh.requestid
 AND rp.value LIKE '/Custom/My Report folder/../../MyReport.xdo'
 AND pp.requestid = rh.requestid
 AND rh.processstart = (
  SELECT max(rhs.processstart)
  FROM fusion_ora_ess.request_history_view rhs
   ,fusion_ora_ess.request_property_view rps
  WHERE 1 = 1
   AND rps.requestid = rhs.requestid
   AND rps.value = rp.value
   AND rhs.executable_status = 'SUCCEEDED'
  )
 AND pp.NAME = 'report_params'
 AND rh.executable_status = 'SUCCEEDED'
 ;
Oracle HCM Cloud Approval Transactions Query

You can use below SQL as a reference to build your report to fetch the approval transactions per your need.

SELECT A.*
FROM
(
SELECT txnh.module_identifier ProcessName,
  wft.creator Requestor,
  wft.assignees CurrentAssignee,
  wft.assigneddate AssignedDate,
  wft.title NotificationTitle,
  txnd.status TxnStatus,
  txnh.object ObjectName
FROM fusion.per_all_people_f dp,
  fusion.per_person_names_f_v n,
  fusion.per_all_assignments_m asg,
  fusion.hrc_txn_header txnh,
  fusion.hrc_txn_data txnd,
  fa_fusion_soainfra.WFTASK wft
WHERE dp.person_id             =n.person_id
AND asg.person_id              =n.person_id
AND LENGTH(asg.assignment_type)=1
AND asg.assignment_id          =txnh.object_id
AND wft.identificationkey      =TO_CHAR(txnh.transaction_id)
AND txnh.object                ='PER_ALL_ASSIGNMENTS_M'
AND txnh.transaction_id        =txnd.transaction_id
AND sysdate BETWEEN asg.effective_start_date AND asg.effective_end_date
AND asg.effective_latest_change='Y'
AND sysdate BETWEEN dp.effective_start_date AND dp.effective_end_date
AND sysdate BETWEEN n.effective_start_date AND n.effective_end_date
UNION
SELECT txnh.module_identifier ProcessName,
  wft.creator Requestor,
  wft.assignees CurrentAssignee,
  wft.assigneddate AssignedDate,
  wft.title NotificationTitle,
  txnd.status TxnStatus,
  txnh.object ObjectName
FROM fusion.per_all_people_f dp,
  fusion.per_person_names_f_v n,
  fusion.per_all_assignments_m asg,
  fusion.hrc_txn_header txnh,
  fusion.hrc_txn_data txnd,
  fa_fusion_soainfra.WFTASK wft
WHERE dp.person_id             =n.person_id
AND asg.person_id              =n.person_id
AND LENGTH(asg.assignment_type)=1
AND asg.period_of_service_id   =txnh.object_id
AND wft.identificationkey      =TO_CHAR(txnh.transaction_id)
AND txnh.object                ='PER_PERIODS_OF_SERVICE'
AND txnh.transaction_id        =txnd.transaction_id
AND sysdate BETWEEN asg.effective_start_date AND asg.effective_end_date
AND asg.effective_latest_change='Y'
AND sysdate BETWEEN dp.effective_start_date AND dp.effective_end_date
AND sysdate BETWEEN n.effective_start_date AND n.effective_end_date
UNION
SELECT txnh.module_identifier ProcessName,
  wft.creator Requestor,
  wft.assignees CurrentAssignee,
  wft.assigneddate AssignedDate,
  wft.title NotificationTitle,
  txnd.status TxnStatus,
  txnh.object ObjectName
FROM fusion.hrc_txn_header txnh,
  fusion.hrc_txn_data txnd,
  fa_fusion_soainfra.WFTASK wft
WHERE wft.identificationkey =TO_CHAR(txnh.transaction_id)
AND txnh.object             ='PER_ALL_PEOPLE_F'
AND txnh.transaction_id     =txnd.transaction_id
) A
order by A.TxnStatus

Wednesday, May 11, 2011

Useful pointers in OAF

Profile options in OAF:

• Personalize Self-Service Defn
           – Yes to allow ‘Personalize’ button to appear at the top of the page
• FND: Personalization Region Link Enabled
           – Yes to display all the regional links above each region
           – Minimal to display key regional links
• Disable Self-Service Personal
           – Yes will disable all personalizations at any level
• FND: Diagnostics
           – Turns on ‘About this Page’
• FND: Personalization Document Root Path (new in 11.5.10)
           – Required to migrate personalizations
           – Set this profile option to a tmp directory with open (777) permissions

********************************************************************************
JDR API


jdr_utils.listcustomizations();
jdr_utils.printdocument();
jdr_utils.deletedocument();


Command list  for deleting substitution-
SQL> exec jdr_utils.listcustomizations('/oracle/apps/pos/changeorder/server/PosRevisionHistoryVO');
/oracle/apps/pos/changeorder/server/customizations/site/0/PosRevisionHistoryVO
PL/SQL procedure successfully completed.

SQL> exec jdr_utils.deletedocument('/oracle/apps/pos/changeorder/server/customizations/site/0/PosRevisionHistoryVO');
PL/SQL procedure successfully completed.

SQL> commit;
Commit complete.

SQL> exec jdr_utils.listcustomizations('/oracle/apps/pos/changeorder/server/PosRevisionHistoryVO');
PL/SQL procedure successfully completed.

Similarly you can also list all the customization done on a particular page or region or even VO using below commands:
SQL>exec jdr_utils.listcustomizations('/oracle/apps/asn/lead/webui/ASNLeadQryRN');
..............
..............

SQL>exec jdr_utils.listcustomizations('/oracle/apps/asn/dashboard/webui/DashboardPG ');
..............
..............
SQL>exec jdr_utils.listcustomizations('/oracle/apps/ar/hz/components/contact/server/HzPuiContRelTableVO');
...............
...............

JDR Utility Tables which store the personalization details:

JDR_ATTRIBUTES
JDR_ATTRIBUTES_TRANS
JDR_COMPONENTS
JDR_PATHS

********************************************************************************
XML Import and Export Commands for OAF pages:

1) Command to import the XML page into the database
adjava -mx128m -nojit oracle.jrad.tools.xml.importer.XMLImporter $JAVA_TOP/oracle/apps/xxvm/iExpensePolicyPage/webui/iExpensePolicyPG.xml -username apps -password appspwd -dbconnection "(description=(address=(protocol=tcp)(host=<host name>)(port=1521))(connect_data=(sid=<SID>)))" -rootdir $JAVA_TOP

OR


adjava \
oracle.jrad.tools.xml.importer.XMLImporter \
$HOME/CHR11/XXDOMI_POS_SUMMARY_VIEW/oracle/apps/pos/planning/webui/customizations/site/0/PosHorizSchdCVPG.xml \
-rootdir $HOME/CHR11/XXDOMI_POS_SUMMARY_VIEW \
-rootPackage / \
-username apps \
-password pwd \
-dbconnection "<Host Name>:<Port Number>:<SID>"


2) Command to Export the XML page from the database:
java oracle.jrad.tools.xml.exporter.XMLExporter oracle/apps/ap/oie/audit/webui/OIE_AUD_AUDIT_PAGE -rootdir /export/home/applvmd -username apps -password appspwd -dbconnection "(description=(address=(protocol=tcp)(host=<host name>)(port=1521))(connect_data=(sid=<SID>)))"

3) Command for VO substitution in an instance.

adjava \
oracle.jrad.tools.xml.importer.JPXImporter $HOME/CHR11/XXDOMI_POS_SUMMARY_VIEW/iSupplierPortal.jpx \

-username apps \
-password pwd \
-dbconnection "<Host Name>:<Port Number>:<SID>"




********************************************************************************

How to Find the Correct Version of JDeveloper to Use with E-Business Suite 11i or Release 12.x (Doc ID 416708.1)

1) First when you log in oracle applications, type in the below in the URL
http:///OA_HTML/OAInfo.jsp

2) Then you get the Oracle Apps version you working on like below

OA Framework Version Information
OA Framework Version 11.5.10.2CU.
MDS Version 9.0.5.4.81 (build 481)
UIX Version 2.2.18
BC4J Version 9.0.3.13.51

3) so my version of apps (OAF) is 11.5.10.2CU

4) go to METALINK and search for Doc ID: Note:416708.1

there you find the below in form of a TABLE.

https://metalink.oracle.com/metalink/plsql/f? p=130:14:7711961564797583862::::p14_database_id,p14_doc id,p14_show_header,p14_show_help,p14_black_frame,p14_fo nt:NOT,416708.1,1,1,1,helvetica

click the above link

there you can select the PATCH as per your version of OAF in u r Oracle Apps.

MINE is PATCH 4573517 for 11.5.10.2CU

Another alternative approach to find the OA Version

Identify the OA Framework version in your instance by activating diagnostics and click the "About This Page" from any OAF page. Click the "Technology Components" tab. The OA Framework version in the top row of the table can then be matched to the JDeveloper Patch.

Release 11i

OA Framework 5.10 patch
Oracle JDeveloper 9i Patch
ATG.PF.H (patch 3438354 or Oracle Applications 11.5.10)
Patch 4045639 9IJDEVELOPER WITH OA EXTENSION ARU FOR FWK.H
ATG PF CU1 (patch 4017300)
Patch 4141787 9IJDEVELOPER WITH OA EXTENSION ARU FOR CU1
ATG PF CU2 (patch 4125550)
Patch 4573517 Oracle9i JDeveloper with OA Extension for 11.5.10 CU2
11i.ATG_PF.H RUP3 (patch 4334965)
Patch 4725670 9IJDEVELOPER WITH OA EXTENSION ARU FOR 11i10 RUP3
11i.ATG_PF.H RUP4 (patch 4676589)
Patch 5455514 9IJDEVELOPER WITH OA EXTENSION ARU FOR 11i10 RUP4
11i.ATG_PF.H RUP5 (patch 5473858)
Patch 6012619 9IJDeveloper With OA Extension ARU FOR 11i10 RUP5
11i.ATG_PF.H.RUP6 (patch 5903765)
Patch 6739235 9IJDeveloper With OA Extension ARU FOR 11i10 RUP6
11i.ATG_PF.H.delta.7 (patch 6241631)
Patch 8751878 9I JDEVELOPER WITH OA EXTENSION ARU FOR 11I RUP7

Release 12.0

ATG Release 12 Version
Oracle JDeveloper 10g Patch
12.0.0
Patch 5856648 10g Jdev with OA Extension
12.0.1  (patch 5907545)
Patch 5856648 10g Jdev with OA Extension
12.0.2  (patch 5484000 or 5917344)
Patch 6491398 10g Jdev with OA Extension ARU for R12 RUP2 (replaces 6197418)
12.0.3  (patch 6141000 or 6077669)
Patch 6509325 10g Jdev with OA Extension ARU for R12 RUP3
12.0.4 (patch 6435000 or 6272680)
Patch 6908968 10G JDEVELOPER WITH OA EXTENSION ARU FOR R12 RUP4
12.0.5 (No new ATG code released)
No new JDev patch required
12.0.6  (patch 6728000 or patch 7237006)
Patch 7523554 10G Jdeveloper With OA Extension ARU for R12 RUP6

Release 12.1

ATG Release 12.1 Version
Oracle JDeveloper 10g Patch
12.1 (Controlled Release - only included for completeness)
Patch 7315332 10G Jdev with OA Extension ARU for R12.1 (Controlled Release)
12.1.1 (rapidInstall or patch 7303030)
Patch 8431482 10G Jdeveloper with OA Extension ARU for R12.1.1
12.1.2 (patch 7303033 or patch 7651091)
Patch 9172975 10G JDEVELOPER WITH OA EXTENSION ARU FOR R12.1.2
12.1.3 (patch 9239090 or patch 8919491)
Patch 9879989 10G JDEVELOPER WITH OA EXTENSION ARU FOR R12.1.3
12.1.3.1 (patch 11894708)
Patch 9879989 10G JDEVELOPER WITH OA EXTENSION ARU FOR R12.1.3
12.1.3.2 (patch 15880118)
Patch 9879989 10G JDEVELOPER WITH OA EXTENSION ARU FOR R12.1.3

Release 12.2

ATG Release 12.2 Version
Oracle JDeveloper 10g Patch
12.2
Patch 17513160 10G JDeveloper with OA Extension ARU for R12.2, certfied on Windows 7, Windows XP-SP2, and Linux. Preferred web browser is Microsoft Internet Explorer 6.0 or above.
12.2.3
Patch 17888411 10G JDeveloper with OA Extension ARU for R12.2.3, certfied on Windows 7, Windows XP-SP2, and Linux. Preferred web browser is Microsoft Internet Explorer 8.0 or above for the Skyros Look-and-Feel and Internet Explorer 6.0 or above for the Swan Look-and-Feel.



Wednesday, April 27, 2011

Sales Order Flow Statuses

OE_ORDER_LINES_ALL.flow_status_code column values

execute the below query to see the values.
SELECT *
FROM fnd_lookup_values
WHERE lookup_type = 'LINE_FLOW_STATUS'
AND language = 'US'


WSH_DELIVERY_DETAILS.Release_Status can have any of the below valide values

Pick Status   Meaning                Description
-----------      --------                   -----------------
  B        Backordered                 Line failed to be allocated in Inventory
  D        Cancelled                     Line is Cancelled
  L        Closed                          Line has been Received
  I         Interfaced                     Line has been shipped and interfaced to Order Management and Inventory
  X        Not Applicable              Line is not applicable for Pick Release
  N        Not Ready to Release     Line is not ready to be released
  P        Purged                          Line has been purged from source system
  R        Ready to Release           Line is ready to be released
  S        Released to Warehouse   Line has been released to Inventory for processing
  C        Shipped                         Line has been shipped
  Y        Staged/Pick Confirmed   Line has been picked and staged by Inventory


WSH_NEW_DELIVERIES.status_code column values

SELECT *
FROM fnd_lookup_values
WHERE lookup_type = 'TRIP_STATUS'
AND language = 'US'

Trip Status   Meaning      Description
-----------      --------         -----------------
  OP          Open         Trip is Open and has not begun
  IT           In-Transit   Trip is in-transit and has begun
  CL          Closed       Trip has completed   

Thursday, April 7, 2011

Value Set types in Oracle Applications

Value Sets

Validation Types in Value Set:

1. Dependent (In order to create a dependent values set you need to create one Independent value set first)
2. Independent
3. None
4. Pair
5. Special
6. Table
7. Translatable Independent
8. Translatable Dependent


  • None: This type allows users to enter any value as long as the value meets value set formatting rules. As this value set is not validated, a segment using this value set does not provide list of values. Ex: If the value set does not allow alphabetic characters, we cannot enter “ABC” but can enter “123”.
  • Independent: This type provides a predefined list of values associated with descriptions. Ex: The meaning of value in this value set does not depend on any other value of any other segment.
  • Table: This type provides a predefined list of values like an independent set but its values are stored in an application table. We define which table to use along with a “where” clause to limit the values to be used.
  • Dependent: This type is similar to independent value set except that the available values and their meanings depend on the independent value that was selected in the prior segment of the flex field. Ex: The Item type depends on what type is chosen in the Item Code field.
  • Special and Pair Value sets: These provide a mechanism to allow “Flex field within a Flex Field” structure. These value sets are primarily used for Standard Request Submission (SRS) parameters, and are not used for normal flex fields. For a Pair value set, two flex fields provide a range of valid values.
  • Translatable Dependent and Translatable Independent: These value types are similar to Dependent and Independent value sets except that they provide a predefined list of values for the segment, also these values can be translated into different languages

Questions on Oracle Value sets


1. Use of Special type of value set.

>> Special type is used for flexifields. Below are some examples for reference:

NOTE: Validate type of Pair will also have similar structure.

Value Set Name: AR_ARZACS_VAL_GLDATE_STANDARD
Validation Type: Special
Click on Edit Information button.
Event = Validate
Funtion =
AR VAL_GLDATE
GL_DATE=:!VALUE
SET_OF_BOOKS_ID=:$PROFILES$.GL_SET_OF_BKS_ID
VGL_DATE_FORMAT="DD-MON-YYYY"

Value Set Name: AP_GL_SRS_FLEXFIELD
Validation Type: Special
Click on Edit Information button.
Event = Edit
Funtion =
FND POPID
APPL_SHORT_NAME=SQLGL
CODE="GL#"
NUM=:$FLEX$.GL_SRS_CHART_OF_ACCOUNTS_ID
REQUIRED=Y
VALIDATE=FULL
ID=:!ID
SEG=:!VALUE
DESC=:!MEANING
NAVIGATE=!DIR
DINSERT=N

Event = Load
Funtion =
FND LOADID
APPL_SHORT_NAME=SQLGL
CODE="GL#"
NUM=:$FLEX$.GL_SRS_CHART_OF_ACCOUNTS_ID
REQUIRED=Y
VALIDATE=FULL
ID=:!ID
SEG=:!VALUE
DESC=:!MEANING
NAVIGATE=!DIR
DINSERT=N


Value Set Name: AP_SRS_APXINREV_COMPANY_SEGMENT
Validation Type: Special
Click on Edit Information button.
Event = Edit
Funtion =
FND POPID
APPL_SHORT_NAME=SQLGL
CODE="GL#"
NUM=:$FLEX$.AP_APXINREV_CHART_OF_ACCOUNTS_NO_VALIDATION
REQUIRED=Y
VALIDATE=NONE
ID=:!VALUE
SEG=:!VALUE
DESC=:!MEANING
DINSERT=N
DISPLAY=GL_BALANCING
ALLOWNULLS="Y"
BOX=Y

Event = Validate
Funtion =
FND VALID
APPL_SHORT_NAME=SQLGL
CODE="GL#"
NUM=:$FLEX$.AP_APXINREV_CHART_OF_ACCOUNTS_NO_VALIDATION
REQUIRED=N
VALIDATE=NONE
ID=:!VALUE
SEG=:!VALUE
DESC=:!MEANING
DINSERT=N
BOX=Y
DISPLAY=GL_BALANCING


2. Use of $FLEX$ in value set

>> :$FLEX$ is used for dependent condition of the parent value set which is of type table.

This example is from flexfield user guide.

Example of $FLEX$ Syntax
Here is an example of using :$FLEX$.Value_Set_Name to set up value sets where one segment depends on a prior segment that itself depends on a prior segment ("Cascading Dependencies")

Assume you have a three-segment flexfield where the first segment is car manufacturer, the second segment is car model, and the third segment is car color. You could limit your third segment’s values to only include car colors that are available for the car specified in the first two segments. Your three value sets might be defined as follows:

Segment Name Manufacturer
Value Set Name Car_Maker_Name_Value_Set
Validation Table CAR_MAKERS
Value Column MANUFACTURER_NAME
Description Column MANUFACTURER_DESCRIPTION
Hidden ID Column MANUFACTURER_ID
SQL Where Clause (none)

Segment Name Model
Value Set Name Car_Model_Name_Value_Set
Validation Table CAR_MODELS
Value Column MODEL_NAME
Description Column MODEL_DESCRIPTION
Hidden ID Column MODEL_ID
SQL Where Clause WHERE MANUFACTURER_ID =
:$FLEX$.Car_Maker_Name_Value_Set

Segment Name Color
Value Set Name Car_Color_Name_Value_Set
Validation Table CAR_COLORS
Value Column COLOR_NAME
Description Column COLOR_DESCRIPTION
Hidden ID Column COLOR_ID
SQL Where Clause WHERE MANUFACTURER_ID =
:$FLEX$.Car_Maker_Name_Value_Set AND
MODEL_ID = :$FLEX$.Car_Model_Name_Value_Set

In this example, MANUFACTURER_ID is the hidden ID column and MANUFACTURER_NAME is the value column of the car_Maker_Name_Value_Set value set. The Model segment uses the hidden ID column of the previous value set, Car_Maker_Name_Value_Set, to compare against its WHERE clause. The end user never sees the hidden ID value for this example.

Another example found on the internet, which talks about using PL/SQL code or calling database functions:

Oracle Special Value Set

Special value set configuration and uses.

I have observed that many times we need to restrict users to a limited, conditional value entries either in DFF or when submitting concurrent request. Normally we can use dependent value set, but when dynamic or some specific check is required, then special value set is better and only choice. Below I have described all the steps for configuring value set. Assign this value set to DFF or concurrent req. parameter as required.

1. Go to Application Developer --> Application --> Validation --> Set.
2. Create a new value set - Enter value set name, description, List type = List of values.
3. Select Validation Type = Special from left bottom of the screen.
4. Click on Edit information.
5. Select Event = Validate.
6. Now in function, you can write pl/sql code or call any function from database.
7. The logic of validation will be as per requirement.
8. The code syntax will be FND PLSQL " entire function "
9. To read the value which user has entered in DFF or as conc. request parameter, use lc_in := :!value;
10. To raise error if the enter value is not correct, use fnd_message.raise_error;
11. Use Application message. Display appropriate message.
12. Raising error makes sure that user cannot continue with the invalid value and he will be forced to correct entry.
13. The character size is limited, but by calling database function, one can put complex validation.

-- Below is the code to validate that user can select a date which is 3 months before sysdate. This is a parementer in report in which user should be allowed to see data for 3 months or before, but he cannot see recent quater data.

FND PLSQL "declare
  l_value varchar2( 20 ) := :!value ;
  l_valid NUMBER := 0 ;
BEGIN
  SELECT (sysdate - to_date(l_value,'dd-mon-yyyy'))
  INTO l_valid
  FROM dual;
  IF (l_valid <= 91) THEN
      fnd_message.set_name( 'FND', 'FND_GENERIC_MESSAGE' ) ;
      fnd_message.set_token( 'MESSAGE', 'Date must be atleast 3 calendar months prior to current date' );
      fnd_message.raise_error ;
  END IF ;
END;
"


3. How to create a value set which is dependent of another value set. (let us consider a value set which displays me the country name, state, in this the country value set is the parent and state value set is child . pls do explain me how to create these two value sets.)

>> You can create dependent value sets in 2 ways.
1) Create one independent then create one dependent and mention the independent one.
2) Create on table type, create another table type and specify the where clause as mentioned above.


4. How to create a value set using 3 tables?

>> You can create value set using multiple table. Give the table names seperated by , in the table name field.
Go through any seeded value set which is based on multiple tables.
Example:

Friday, April 1, 2011

Data flow of Standard Sales Order in OM

1. Order Entry

This is the first stage when Order in entered in the system. When order is entered it basically create a record in order headers and Order Lines tables.

•OE_ORDER_HEADERS_ALL (Here the flow_status_code = Entered)
•OE_ORDER_LINES_ALL (flow_status_code = Entered) ( order number is generated)
•OE_ORDER_HOLDS_ALL - If any hold is applied for order like credit check etc

2.Order Booking

This is next stage , when Order is booked, the Flow status changes from Entered to Booked. At this stage , these table get affected.

•OE_ORDER_HEADERS_ALL (flow_status_code = Booked, booked_flag updated)
•OE_ORDER_LINES_ALL (flow_status_code = Awaiting Shipping, booked_flag updated)
•WSH_NEW_DELIVERIES (status_code OP open)
•WSH_DELIVERY_DETAILS (released_status = 'R' - Ready to Release)
Same time, Demand interface program runs in background and inserts into inventory tables MTL_DEMAND

3. Reservation

This step is required for doing reservations SCHEDULE ORDER PROGRAM runs in the background and quantities are reserved. Once this program get successfully completed, the MTL_RESERVATIONS table get updated.

4. Pick Release

Ideally pick release is the process which is defined in which the items on the sales order are taken out from inventory into the staging area.

Normally pick release SRS program runs in background. Once the program get completed these are the table get affected:

•OE_ORDER_LINES_ALL (flow_status_code = PICKED)
•WSH_DELIVERY_DETAILS (released_status = 'S' - Released to Warehouse means "Line has been released to Inventory for processing")
•MTL_TXN_REQUEST_HEADERS
•MTL_TXN_REQUEST_LINES
(move order tables. Here request is generated to move item from saleble to staging sub inventory)
•MTL_MATERIAL_TRANSACTIONS_TEMP (link to above tables through move_order_header_id/line_id

5.Pick Confirm

Items are transferred from saleble to staging Subinventory.

•MTL_MATERIAL_TRANSACTIONS
•MTL_TRANSACTION_ACCOUNTS
•WSH_DELIVERY_DETAILS (released_status = 'Y' - Staged/Pick Confirmed means "Line has been picked and staged by Inventory")
•WSH_DELIVERY_ASSIGNMENTS

6.Ship Confirm

Here ship confirm interface program runs in background. Data removed from WSH_NEW_DELIVERIES

•OE_ORDER_LINES_ALL (flow_status_code "SHIPPED")
•WSH_DELIVERY_DETAILS (released_status 'C' - Shipped means "Line has been shipped")
•MTL_TRANSACTION_INTERFACE
•MTL_MATERIAL_TRANSACTIONS(linked through Transaction source header id)
•MTL_TRANSACTION_ACCOUNTS
•Data deleted from MTL_DEMAND,MTL_RESERVATIONS
•Item deducted from MTL_ONHAND_QUANTITIES

7.Enter Invoice

This is also called Receivables interface, that mean information moved to accounting area for invoicing details.

•Invoicing workflow activity transfers shipped item information to Oracle Receivables.
•RA_INTERFACE_LINES_ALL (interface table into which the data is transferred from order management)T
•Then AutoInvoice Master Program imports data from this
•Table which get affected into this stage are recievables base table.
◦RA_CUSTOMER_TRX_ALL (cust_trx_id is primary key to link it to trx_lines table and trx_number is the invoice number)
◦RA_CUSTOMER_TRX_LINES_ALL (line_attribute_1 and line_attribute_6 are linked to header_id (or order number) and line_id of the orders)

8.Complete Line

In this stage order line leval table get updated with Flow status and open flag.

•OE_ORDER_LINES_ALL (flow_status_code = 'CLOSED', open_flag 'N')

9.Close Order

This is last step of Order Processing . In this stage only OE_ORDER_HEADERS_ALL table get updated.

These are the table get affected in this step.

•OE_ORDER_HEADRES_ALL (flow_status_code = CLOSED, open_flag 'N')
These are the typically data flow of a order to cash model for a standard order.

Wednesday, March 23, 2011

Drop Shipment Order Flow




More details can be found in the below website:
Order Management Functional



1.Order Entry

Here the activity is entering process where oe_order_headers_all (flow_status_code as entered) oe_order_lines_all . The order is booked as DROP SHIP

2. Order Booking

3. The Purchase Release program passes information about eligible drop-ship order lines to Oracle Purchasing.The interface table which gets populated is
po_requisitions_interface_all & po_req_dist_interface_all

4. After Purchase Release has completed successfully, run Requisition Import in Oracle Purchasing to generate purchase requisitions for the processed order lines. The Requisition Import program reads the above interface tables, validates your data, derives or defaults additional information and writes an error message for every validation that fails into the po_interface_errors table.The validated data is then inserted into the requisition base tables
po_requisition_headers_all,
po_requisition_lines_all,
po_req_distributions_all.
Then use autocreate PO fuctionality to create purchase orders and then perform receipts against these purchase orders

7. After the goods are successfully received invoices for vendors are created in accounts payables as in normal purchase orders.

8. Invoices are generated for customers In account receivables.

9. oe_order_lines_all (flow_status_code 'shipped', open_flag "N")

10. oe_order_lines_all (flow_status_code 'closed', open_flag "N")

More details can be found at http://www.oracleug.com/user-guide/order-management/back-back-orders

Tuesday, February 1, 2011

Oracle Workflow Table details with relationship diagram





A) Some comments on the graphical representation:

The columns belonging to the primary key are indicated in red.

Only the columns that either belong to a primary key or a foreign key are shown on this diagram.
The columns belonging to a foreign key may also belong to a primary key.

This model is split into 2 diagrams. Due to this, sometimes the start or the end point of a foreign key arrow is not on the current diagram.

Due to the graphical representation of foreign key structure, a column name may appear more than once inside a table. Of course this does not mean the column is duplicated within the table.

For a complete description of each of the tables, please refer to:

Oracle eTRM Technical Reference web site: http://etrm.oracle.com or note 150230.1 (ETRM DIRECT ACCESS DOCUMENT).


B) Some comments on workflow tables:

1) Difference between WF_ACTIVITIES and WF_PROCESS_ACTIVITIES

WF_ACTIVITIES contains only the activities that belong to the item type
Does NOT contain activities that belong to other item types (ie pre-defined activities).

WF_PROCESS_ACTIVITIES contains the activities of the item type AND the pre-defined activities that are referenced in the item type.

WF_PROCESS_ACTIVITIES, in addition to its primary key instance_id, has a unique key defined on the following columns:

1.Instance_label
2.Process_item_type
3.Process_name
4.Process_version


2) The following tables have a corresponding translation ( _TL) table:


- WF_ITEM_TYPES
- WF_ITEM_ATTRIBUTES
- WF_ACTIVITIES
- WF_ACTIVITY_ATTRIBUTES
- WF_MESSAGES
- WF_MESSAGE_ATTRIBUTES

The workflow lookup tables only exist as translation (_TL) tables:

WF_LOOKUP_TYPES_TL
WF_LOOKUPS_TL


(Translation tables are not shown in the above diagrams)



3) Difference between WF_ITEM_ACTIVITY_STATUSES and WF_ITEM_ACTIVITY_STATUSES_H

WF_ITEM_ACTIVITY_STATUSES and WF_ITEM_ACTIVITY_STATUSES_H have the same structure.

When the same activity is executed multiple times within a workflow (ie looping activity),
WF_ITEM_ACTIVITY_STATUSES will only contain information on the last execution of the activity, whereas the information on all the previous executions will be stored in WF_ITEM_ACTIVITY_STATUSES_H.

When an activity is executed only once within a workflow, only WF_ITEM_ACTIVITY_STATUSES will be populated.

Oracle Applications : Descriptive Flexfields (DFF) Overview and the SQL to find the Columns & Details.

Descriptive Flexfields

Descriptive flexfields let you satisfy different groups of users without having to reprogram your application, by letting you provide customizable “expansion space”? on your forms.

For example, suppose you have a retail application that keeps track of customers. Your Customers form would normally include fields such as Name, Address, State, Customer Number, and so on. However, your form might not include extra fields to keep track of customer clothing size and color preferences, or regular salesperson, since these are attributes of the customer entity that depend on how your users use your application.

For example, if your retail application is used for a tool company, a field for clothing size would be undesirable. Even if you initially provide all the fields your users need, your users might later identify even more customer attributes that they want to keep track of. You add a descriptive flexfield to your form so that your users have the desired expansion space. Your users can also take advantage of the fact that descriptive flexfields can be context sensitive, where the information your application stores depends on other values your users enter in other parts of the form.

A descriptive flexfield describes an application entity, providing form and database expansion space that you can customize. Each descriptive segment has a name you assign. You can specify valid segment values or set up criteria to validate the entry of any value.

Oracle General Ledger includes a descriptive flexfield in its journal entry form to allow end users to add information of their own choosing. For example, end users might want to capture additional information about each journal entry, such as source document number or the name of the person who prepared the entry. You could use a descriptive flexfield in a fixed assets application you build to allow further description of a fixed asset. You could let the structure of your assets flexfield depend on the value of an asset type field. For example, if asset type were “desk”, your descriptive flexfield could prompt for style, size and wood type. If asset type were “computer”, your descriptive flexfield could prompt for CPU chip and memory size.

SELECT fdfv.title
,fdfv.application_table_name
,fdfv.context_column_name
,fdfcu.descriptive_flexfield_name
,fdfcu.descriptive_flex_context_code
,fdfcu.column_seq_num
,fdfcu.application_column_name
,fdfcu.end_user_column_name
FROM fnd_descr_flex_col_usage_vl fdfcu
fnd_descriptive_flexs_vl fdfv
WHERE fdfv.title = 'Line Transaction Flexfield'
AND fdfcu.descriptive_flexfield_name = fdfv.descriptive_flexfield_name
AND fdfcu.application_id = fdfv.application_id
ORDER BY fdfcu.descriptive_flexfield_name
,fdfcu.descriptive_flex_context_code
,fdfcu.column_seq_num ;

SELECT fdfv.title,
,fdfv.application_table_name
,fdfv.context_column_name
,fdfcu.descriptive_flexfield_name
,fdfcu.descriptive_flex_context_code
,fdfcu.column_seq_num
,fdfcu.application_column_name
,fdfcu.end_user_column_name
FROM fnd_descr_flex_col_usage_vl fdfcu
,fnd_descriptive_flexs_vl fdfv
WHERE fdfv.title = 'Invoice Transaction Flexfield'
AND fdfcu.descriptive_flexfield_name = fdfv.descriptive_flexfield_name
AND fdfcu.application_id = fdfv.application_id
ORDER BY fdfcu.descriptive_flexfield_name
,fdfcu.descriptive_flex_context_code
,fdfcu.column_seq_num ;


SELECT fdfv.title,
,fdfv.application_table_name
,fdfv.context_column_name
,fdfcu.descriptive_flexfield_name
,fdfcu.descriptive_flex_context_code
,fdfcu.column_seq_num
,fdfcu.application_column_name
,fdfcu.end_user_column_name
FROM fnd_descr_flex_col_usage_vl fdfcu
,fnd_descriptive_flexs_vl fdfv
WHERE fdfv.title = 'Reference Transaction Flexfield'
AND fdfcu.descriptive_flexfield_name = fdfv.descriptive_flexfield_name
AND fdfcu.application_id = fdfv.application_id
ORDER BY fdfcu.descriptive_flexfield_name
,fdfcu.descriptive_flex_context_code
,fdfcu.column_seq_num ;


SELECT fdfv.title,
,fdfv.application_table_name
,fdfv.context_column_name
,fdfcu.descriptive_flexfield_name
,fdfcu.descriptive_flex_context_code
,fdfcu.column_seq_num
,fdfcu.application_column_name
,fdfcu.end_user_column_name
FROM fnd_descr_flex_col_usage_vl fdfcu
,fnd_descriptive_flexs_vl fdfv
WHERE fdfv.title = 'Link-to Transaction Flexfield'
AND fdfcu.descriptive_flexfield_name = fdfv.descriptive_flexfield_name
AND fdfcu.application_id = fdfv.application_id
ORDER BY fdfcu.descriptive_flexfield_name
,fdfcu.descriptive_flex_context_code
,fdfcu.column_seq_num ;

Oracle applications - Key Flex Field Structures & Table Details.

Here is some of quite commonly used AOL FND (Foundation) tables and their usage. There are many other tables also in FND but here i am putting only few commonly used tables. for other table if needed we can dig further.

FND_ID_FLEXS stores registration information about key flexfields. Each row includes the four–character code that identifies the key flexfield, the title of the flexfield (by which a user identifies theflexfield), the name of the combinations table that contains the key flexfield columns, and the name of the structure defining (MultiFlex) column for the flexfield (SET_DEFINING_COLUMN_NAME). Each row also contains values that identify the application that owns the combination table and the application that owns the key flexfield, a table–type flag that specifies whether the combinations table is specificor generic (S or G), whether dynamic inserts are feasible for the flexfield(Y or N), whether the key flexfield can use ID type value sets, and the name of the unique ID column in the combinations table. You need one row for each key flexfield in each application. Oracle Application ObjectLibrary uses this information to generate a compiled key flexfield definition

FND_ID_FLEX_SEGMENTS: FND_ID_FLEX_SEGMENTS stores setup information about keyflexfield segments, as well as the correspondences between application table columns and the key flexfield segments the columns are used for. Each row includes a flexfield application identifier, the flexfield code,which identifies the key flexfield, the structure number(ID_FLEX_NUM), the value set application identifier, the segment number (the segment’s sequence in the flexfield window), the name of the column the segment corresponds to (usually SEGMENTn, where n is an integer). Each row also includes the segment name, whether security is enabled for the segment, whether the segment is required, whether the segment is one of a high, low segment pair, whether the segment is displayed, whether the segment is enabled (Y or N), type of default value, display information about the segment such as prompts and display size, and the value set the segment uses. Each row also includes a flag for whether the table column is indexed; this value is normally Y. You need one row for each segment of each structure for each flexfield. Oracle Application Object Library uses this information to generate a compiled key flexfield definition to store in the FND_COMPILED_ID_FLEXS table Thanks – Shivmohan Purohit

FND_ID_FLEX_STRUCTURES : FND_ID_FLEX_STRUCTURES stores structure information about keyflexfields. Each row includes the flexfield code and the structurenumber (ID_FLEX_NUM), which together identify the structure, and the name and description of the structure. Each row also includes values that indicate whether the flexfield structure is currently frozen, whether rollup groups are frozen (FREEZE_STRUCTURED_HIER_FLAG), whether users can dynamically insert new combinations of segment values through the flexfield pop–up window, and whether the flexfield should use segment cross–validation rules. Each row also contains information about shorthand flexfield entry for this structure, including whether shorthand entry is enabled, the prompt for the shorthand window, and the length of the shorthand alias field in the shorthandwindow. You need one row for each structure of each key flexfield. Oracle Application Object Library uses this information to generate acompiled key flexfield definition to store in the FND_COMPILED_ID_FLEXS table

FND_FLEX_VALUES stores valid values for key and descriptive flexfield segments. Oracle Application Object Library uses this table when users define values for independent or dependent type value sets. Oracle Application Object Library also uses this table when users define parent values for ranges of child values that exist in a validation table(Oracle Application Object Library stores the parent values in this table). Each row includes the value (FLEX_VALUE) and its hierarchy level if applicable as well as the identifier of the value set the value belongs to. If the value is a dependent value, PARENT_FLEX_VALUE_LOW contains the independent value this value depends upon. Oracle Application Object Library does not use the PARENT_FLEX_VALUE_HIGH column. If ENABLED_FLAG contains N, this value is currently invalid, regardless of the start and end dates.

If ENABLED_FLAG contains Y, the start and end dates indicate if this value is currently valid.SUMMARY_FLAG indicates if this value is a parent value that has child values, and STRUCTURED_HIERARCHY_LEVEL contains the rollup group the parent value belongs to, if any (1 through 9). COMPILED_VALUE_ATTRIBUTES contains the compiled values of anysegment qualifiers assigned to this value. These values are in a special Oracle Application Object Library format, and you should never modify them.

VALUE_CATEGORY and ATTRIBUTE1 through ATTRIBUTE50 are descriptive flexfield columns, where VALUE_CATEGORY is the context (structure defining) column.

These descriptive flexfield columns do not contain values unless you have defined the descriptive flexfield at your site. You need one row for each independent, dependent or parent value belonging to a value set.Oracle Application Object Library uses this information to ensure that users enter valid values in flexfield segments

FND_FLEX_VALUE_HIERARCHIES stores information about child value ranges for key flexfield segment values. Each row includes an identification of the parent value the range belongs to, as well as the low and high values that make up the range of child values. FLEX_VALUE_SET_ID identifies the value set to which the parent value belongs. You need one row for each range of child values (you can have more than one row for each parent value). Oracle Application Object Library provides this information for applications reporting purposes.

SELECT
B.APPLICATION_ID, B.ID_FLEX_CODE, B.ID_FLEX_NUM,
B.ID_FLEX_STRUCTURE_CODE,
B.CONCATENATED_SEGMENT_DELIMITER,
B.CROSS_SEGMENT_VALIDATION_FLAG, B.DYNAMIC_INSERTS_ALLOWED_FLAG, B.ENABLED_FLAG,
B.FREEZE_FLEX_DEFINITION_FLAG, B.FREEZE_STRUCTURED_HIER_FLAG, B.SHORTHAND_ENABLED_FLAG,
T.ID_FLEX_STRUCTURE_NAME, T.DESCRIPTION
FROM FND_ID_FLEX_STRUCTURES_TL T, FND_ID_FLEX_STRUCTURES B
WHERE B.APPLICATION_ID = T.APPLICATION_ID
AND B.ID_FLEX_CODE = T.ID_FLEX_CODE
AND B.ID_FLEX_NUM = T.ID_FLEX_NUM
AND T.LANGUAGE = userenv(‘LANG’)
AND B.ENABLED_FLAG = ‘Y’
AND B.FREEZE_STRUCTURED_HIER_FLAG = ‘Y’
AND B.ID_FLEX_CODE = ‘GL#’
AND B.ID_FLEX_NUM = &&number
Here are some more SQLs to find the GL combinations structures:

SELECT s.FLEX_VALUE_SET_ID,s.FLEX_VALUE_SET_NAME, v.FLEX_VALUE, t.DESCRIPTION
FROM fnd_flex_values v,fnd_flex_value_sets s,fnd_flex_values_tl t
WHERE FLEX_VALUE_SET_NAME LIKE ‘%&&Company_Department%’
AND s.FLEX_VALUE_SET_ID = v.FLEX_VALUE_SET_ID
AND t.FLEX_VALUE_ID = v.FLEX_VALUE_ID
ORDER BY FLEX_VALUE
SELECT s.FLEX_VALUE_SET_ID,s.FLEX_VALUE_SET_NAME, v.FLEX_VALUE, t.DESCRIPTION
FROM fnd_flex_values v,fnd_flex_value_sets s,fnd_flex_values_tl t
WHERE FLEX_VALUE_SET_NAME LIKE ‘%&&Company_Account%’
AND s.FLEX_VALUE_SET_ID = v.FLEX_VALUE_SET_ID
AND t.FLEX_VALUE_ID = v.FLEX_VALUE_ID
ORDER BY FLEX_VALUE

SELECT s.FLEX_VALUE_SET_ID,s.FLEX_VALUE_SET_NAME, v.FLEX_VALUE, t.DESCRIPTION
FROM fnd_flex_values v,fnd_flex_value_sets s,fnd_flex_values_tl t
WHERE FLEX_VALUE_SET_NAME LIKE ‘%&&Company_Future%’
AND s.FLEX_VALUE_SET_ID = v.FLEX_VALUE_SET_ID
AND t.FLEX_VALUE_ID = v.FLEX_VALUE_ID
ORDER BY FLEX_VALUE

SELECT s.FLEX_VALUE_SET_ID,s.FLEX_VALUE_SET_NAME, v.FLEX_VALUE, t.DESCRIPTION
FROM fnd_flex_values v,fnd_flex_value_sets s,fnd_flex_values_tl t
WHERE FLEX_VALUE_SET_NAME LIKE ‘%&&Company_Location_FA%’
AND s.FLEX_VALUE_SET_ID = v.FLEX_VALUE_SET_ID
AND t.FLEX_VALUE_ID = v.FLEX_VALUE_ID
ORDER BY FLEX_VALUE

SELECT s.FLEX_VALUE_SET_ID,s.FLEX_VALUE_SET_NAME, v.FLEX_VALUE, t.DESCRIPTION
FROM fnd_flex_values v,fnd_flex_value_sets s,fnd_flex_values_tl t
WHERE FLEX_VALUE_SET_NAME LIKE ‘%&&Company_Country_FA%’
AND s.FLEX_VALUE_SET_ID = v.FLEX_VALUE_SET_ID
AND t.FLEX_VALUE_ID = v.FLEX_VALUE_ID
ORDER BY FLEX_VALUE

SELECT s.FLEX_VALUE_SET_ID,s.FLEX_VALUE_SET_NAME, v.FLEX_VALUE, t.DESCRIPTION
FROM fnd_flex_values v,fnd_flex_value_sets s,fnd_flex_values_tl t
WHERE FLEX_VALUE_SET_NAME LIKE ‘%&&Company_State_FA%’
AND s.FLEX_VALUE_SET_ID = v.FLEX_VALUE_SET_ID
AND t.FLEX_VALUE_ID = v.FLEX_VALUE_ID
ORDER BY FLEX_VALUE

SELECT s.FLEX_VALUE_SET_ID,s.FLEX_VALUE_SET_NAME, v.FLEX_VALUE, t.DESCRIPTION
FROM fnd_flex_values v,fnd_flex_value_sets s,fnd_flex_values_tl t
WHERE FLEX_VALUE_SET_NAME LIKE ‘%&&Company_City_FA%’
AND s.FLEX_VALUE_SET_ID = v.FLEX_VALUE_SET_ID
AND t.FLEX_VALUE_ID = v.FLEX_VALUE_ID
ORDER BY FLEX_VALUE

SELECT *
FROM fnd_flex_value_sets a
,fnd_flex_values b
WHERE a.flex_value_set_id = b.flex_value_set_id
AND a.flex_value_set_name like 'YES_NO'

SELECT *
FROM fnd_flex_value_sets a
WHERE a.flex_value_set_name like 'YES_NO'

Monday, January 31, 2011

Useful SQL Hints to improve query performance.

Search: The Web Angelfire
Report Abuse « Previous | Top 100 | Next »
share: del.icio.us | digg | reddit | furl | facebook

ORACLE SQL optimization


Step 1: Find the statements that consume the most resources. You can use the view V$SORT_USAGE to see the session and the SQL associated with a temporary segment which is still in the SQL area.

The statements with the most potential to improve performance if tuned include:
1) The queries that consume the most resources overall.
2) The queries that consume the most resources per row.
3) The queries that are executed most frequently
In the V$SQLAREA you can find the statements which are still in cache and have done a great deal of I/O and buffer gets.

Step 2: Tune those statements to use fewer resources
1) Get the statement to use fewer resources
2) Use the statement less often.

Approaches to tuning SQL statements

1) Restructuring indexes - An index plays an important part in the complete database design. Good index design is just as important as good table design. One of the main reasons for using indexes is so that the database can access the correct data quickly. However too many indexes or have useless indexes can be a burden to the system as they require maintenance when using DML, also the optimizer may choose the wrong index to use if there are too many to choose from, especially in a complex SQL select statement.
a) Remove non selective indexes to speed up DML
b) Index performance critical paths
c) Consider hash clusters, but what out for uniqueness, hashing unique data can produce very large hash indexes.
d) Consider index clusters only if the cluster keys are similar in size.

2) Restructure the statement
a) Consider alternative SQL syntax
e.g. SELECT dname, deptno
FROM dept
WHERE deptno NOT IN (SELCT deptno FROM emp)
A faster version of this statement would be
SELECT dname, deptno
FROM dept
WHERE NOT EXIST
( SELECT deptno FROM emp WHERE dept.deptno = emp.deptno)

b) Compose predicates using AND and =. Using equijoins without exception, statements that perform equijoins on untransformed columns are fastest and easiest to tune.

c) Choose an advantageous join order. Join orders can have a significant effect on performance. The main objective of SQL tuning is to avoid performing unnecessary work, which can slow down the performance of the statement as well as confusing the optimizer to select the wrong method of optimization.
i) Avoid using a full table scan if it is more efficient to get the data through an index.
ii) Avoid using indexes which select too many rows (more than 2-4% of the table number of rows in the table).
iii) Choose a join order so as to join fewer rows.
For example:
SELECT info
FROM taba a, tabb b, tabc c
WHERE
Acol BETWEEN :alow AND :ahigh
AND bcol BETWEEN :blow AND :bhigh
AND ccol BETWEEN :clow AND :chigh
AND a.key1 = b.key1
AND a.key2 = b.key2

i) Choose a driving table and a driving index. The first three rows of the WHERE clause are filter conditions and the last two are join conditions. Filter conditions dominate the choice of the driving table and the driving index. In general the driving table should be the table containing the filter condition which eliminates the most rows.
ii) Choose the right index. Once you have established the driving table, you must choose the most selective index available to drive the table. Alternative is to use a full table scan if that is more efficient; sometimes if there are no effective indexes it is better to do a full table scan as full scans a sequential rather than random access. From there, the joins should all happen through the joined indexes, the index on primary or foreign keys used to connect the table to a earlier table in the join tree. Rarely should you use the indexes on non-join conditions, except for driving the table. In the above example you should use the indexes on b.key1 and c.key2 to drive into tabb and tabc respectively.
iii) Choose the best join order, driving the best unused filters earliest. The work of following a join can be reduced by first joining to the table with the best still unused filter. Thus if 'bcol BETWEEN ¡K' is more restrictive than 'ccol BETWEEN ¡K.', the last join can be made easier if tabb is joined before tabc.

d) Use untransformed column values. Avoid using functions in the WHERE clause of the statement unless it is really necessary. Useful functions such as to_date and to_char and to_number can slow down execution as well as making the optimizer skip useful indexes on the transformed columns.

e) Avoid using mixed expressions and implicit conversions. E.g. < char_val > = < num_val >. In this case the SQL interpreter will perform an implied conversion of to_number = . This may cause two problems; firstly, the optimizer may ignore a good index on char_val and secondly errors from char to num may occur causing the statement to fail. To avoid this problem use explicit conversions e.g. char_val = to_char(num_val).

f) Write separate SQL statements for specific values. SQL is not a procedural language and using it to do many things in one statement is not a good idea. Optimizations (determining the execution plan) takes place before the database knows of the values used as parameters. An execution plan should therefore not depend in what those values are for.
For example:
SELECT info FROM tables WHERE ....
AND acol BETWEEN DECODE(:loval,'ALL',acol,:loval)
AND DECODE(:hival,'ALL',acol,:hival)
Here the optimizer cannot use the index on acol because the column acol appears on both sides of the BETWEEN expression. In these cases you have to change the structure of the SQL statement.
SELECT info FROM tables WHERE ...
AND acol BETWEEN :loval AND :hival
AND (:loval !='ALL' AND :hival !='ALL')
UNION ALL
SELECT info FROM tables WHERE ...
AND (:loval ='ALL' OR :hival !='ALL')

When you run the explain plan on the new SQL statement you will get the desired result and the undesired result in the same plan. One will use an index and the other will uses a full table scan. In the case of both parameters not equal to 'ALL' you would wish to use an index, and in the other case a full table scan will be faster. Although both the desired and the undesired part exist in the execution plan, one part of the UNION ALL will be eliminated upon execution as :hival and :loval can either be 'ALL' or not 'ALL'. This will eliminate the undesired part upon execution. Note also the use of UNION ALL and not just UNION. The purpose is to eliminate the costly SORT (and deleting duplicates) associated with a UNION and not with a UNION ALL.

g) Use control hints. Although the optimizer does a good job getting the best execution plan, it is sometimes not as aware of the overall picture and require a little hint from the developer. Regardless of why the optimizer choose the wrong execution plan, the use of hints can produce better results if used correctly, especially to force the optimizer to choose a certain path such as a full table scan rather than an index.

h) Use care when using IN and NOT IN in a subquery. Remember that WHERE (NOT) EXISTS can be a useful alternative.
i) Use care when embedding value lists. Examine carefully the contents of embedded value list and try to find an alternative if possible.
For example,
SELECT info FROM table
WHERE transport IN ('BMW','HONDA','FORD')
It may be possible instead to use:
SELECT info FROM table
WHERE transport_type = 'CAR'

j) Minimize the use of DISTINCT or GROUP BY unless necessary as they will always create a sort.

k) Reduce the number of calls to the database. Instead of calling an INSERT, UPADTE or DELETE then a SELECT to get the new record from the database, use INSERT¡KRETURNING, UPDATE¡KRETURNING or DELETE¡KRETURNING to perform both tasks in one call.

l) Avoid using views in joins, unless really necessary. Joins take time and also processing the view also tasks time, so avoid putting them together especially in outer joins.

3) Modify or disable triggers. In most cases using triggers can make life a lot easier for the DBA and developer and help to maintain data integrity. However triggers consume resources, and too many or inappropriate triggers can affect performance.

Approaches to creating indexes

Index plays an important part in database design, the efficiency of the optimizer and the reduction of workload on the main tables (especially if most of the information can be found on the index). However, indexes can also be a burden to the system, requiring extra processing from each DML statement issued to the table with an index. Therefore, good index design is essential.
Oracle provides a variety of index types, each with different properties and each with a different use. The following section is some guidelines to creating useful indexes.

1) When creating an index, the target is that the index would help to query less than 2% - 4% of the tables total data.
2) Building indexes just in case is not a bright idea.
3) Avoid building too many indexes. Indexes processing consumes extra resources per INSERT, UPDATE and DELETE.
4) Do not index columns which are frequently modified. For example, order_id, order_number, customer_id may be good indexes, but order_status, last_modification_date are not good indexes even if they may be used in one or two forms and reports.
5) ALTER INDEX ¡K. REBUILD is faster than dropping and recreating the index.
6) Compact indexes. Using ALTER INDEX¡KCOALESCE can be used to rebuild indexes online.
7) Creating index based upon commonly used functions can be a good aid, rather than burden to system if used properly. For example:
CREATE INDEX idx ON table (a+b*(c-1),a,b) can aid
SELECT info FROM table WHERE a+b*(c-1) BETWEEN 25 AND 50
Or
CREATE INDEX ind ON table(UPPER(empname))
8) Create indexes used in commonly used GROUP and ORDER BY clauses.
9) For large indexes which cover more than 5% of the tables data, but are necessary, consider using a BITMAP INDEX. Bitmap indexes use up less space for indexes with not a lot of distinct values and can be faster for this kind of index. However bitmap indexes cannot be declared unique. Another good use of bitmap indexes is the fact that it can index null values, whilst normal indexes do not.

Approaches to using clusters

Cluster
For tables which are joined regularly such as master detail tables, consider a CLUSTER.
Don't use cluster indexes on non frequent joins or fields which are update frequently.
Don't use cluster on tables which regularly performs full index scans. Clustering actually slows down access on individual records in a table.
Consider cluster on master detail tables where the master table is accessed first then the detail table. Clustering actually places the detail table right after the master table, so access is faster.
Consider a detail cluster alone if you select many details from the same master record.
Don't consider clustering if the data from all the tables in the same cluster key uses more than two blocks.

Hash Clusters
Hash clusters are similar to clusters, except that they perform an hash function to each rows cluster key values.
Consider a hash cluster if the WHERE clause of a SQL statement uses conditions that use the same column or combination of columns regularly.
Consider a hash cluster if you can determine the space required to hold all values in the cluster keys. Note: this means that cluster keys are useful for look tables but not for tables updated or change regularly.
Do not use when space is scarce, hash clusters can consume a lot of space.
As mentioned above do not use on a constantly growing table.
Don't use cluster on tables which regularly performs full index scans. Clustering actually slows down access on individual records in a table.
As mentioned above do not use on a regularly modified table.

Approaches to using hints

In the above section, it is mentioned that hints can aid or force the optimizer to use a certain execution plan. This section will describe in more detail the different types of hints that can be used and how they affect the execution plan outcome. Oracle four key optimization plans; they are as follows:
ALL_ROWS - This is used to get the best total performance for the statement. Best used for reports where all the rows must be obtained.
FIRST_ROWS - This is used to get the best response time. Best used for forms and queries where faster response time is required. This mode cannot be used with DML statements, UNIONs, INTERSECTs, MINUS, GROUP BY, FOR UPDATE, DISTINCT.
RULE - This is based on rule based optimizations where predefined optimization rules are used to determine the execution plan.
CHOOSE - Let the optimizer choose the method from the above three rules.

Hints for access method
Hints for optimization (above) control the overall execution plan, however oracle provides hints for control over individual tables and indexes. These are group as access method hints.
FULL(table) - Use full scan on the table specified.
ROWID(table) - Use scan by rowid on the table specified.
CLUSTER(table) - Use a cluster scan on the table specified.
HASH(table) - Use a hash scan on the table specified.
HASH_AJ - use to force optimizer to change all NOT IN into a hash outer join.
HASH_SJ - use to force the optimizer to EXISTS into a hash semi join.
INDEX( table index) - consider the index specified to be used first.
INDEX_ASC(table index) - specifies ascending range of scan of index explicitly.
INDEX_DESC(table index) - specifies descending range of scan of index explicitly.
INDEX_COMBINE(table index) - Chooses a bitmap access path for the table using the index specified.
INDEX_JOIN(table index) - Using index to join explicitly.
INDEX_FFS(table index) - Use a fast full index scan for the table and index specified.
NO_INDEX(table index) - Tells the optimizer to ignore certain indexes.
MERGE_AJ - Transforms a NOT IN into a merged anti join.
MERGE_SJ - transforms a EXISTS subquery into a merged semi join.
AND_EQUAL(table index index) - merges scans on several single column indexes.
USE_CONCAT - forces OR conditions in the WHERE clause into a compound UNION ALL set.
NO_EXPAND - prevents IN list to be expanded into OR conditions.
REWRITE(view) - Rewrite the statement using the view specified instead.
NO_REWRITE - prevents statement from being rewritten with a view.

Hints on join order

ORDERED - causes the optimizer to join the tables in the query in the order they appear in the FROM clause.
STAR - Forces the star query plan. The star query plan has the largest table last in the join order and joins with a nested loop. Star hint applies when there are at least three tables.

Hints on join operators

USE_NL(table) - force to use nested loops for table
USE_MERGE(table) - force to use SORT MERGE for the table.
USE-HASH(table) - force to use hash join for the table.
DRIVING_SITE(table) - force query to be done at a different site.

Examples

The times we taken from a IBM S8a server with 6 CPUs, running Oracle 8i and Oracle Applications 11i.
The important thing is not the time, but the time difference frfom the original statement.

Use of descending indexes (INDEX_DESC)
Original statement
SELECT * FROM ar_payment_schedules_all apsa
WHERE trx_date > sysdate -7
OEDER BY apsa.trx_date desc


PLAN
SELECT STATEMENT, GOAL = RULE
SORT ORDER BY
TABLE ACCESS BY TABLE ROWID AR_PAYMENT_SCHEDULES_ALL
INDEX RANGE SCAN AR_PAYMENT_SCHEDULES_N1

Execution time : 12.897 secs*

Modified
SELECT --+INDEX_DESC(apsa,ar_payment_schedules_n1)
* FROM ar_payment_schedules_all apsa
WHERE apsa.trx_date > sysdate - 7
ORDER BY apsa.trx_date DESC


PLAN
SELECT STATEMENT, GOAL = RULE
SORT ORDER BY
TABLE ACCESS BY TABLE ROWID AR_PAYMENT_SCHEDULES_ALL
INDEX RANGE SCAN DESCENDING AR_PAYMENT_SCHEDULES_N1


Execution time : 3.311 secs*

Fast Full Index scan

Using the above example, we can modify it so that the optimizer uses a fast full index scan. To do this we only select the fields from the index, so that it does not need to use the table, just the index.
SELECT --+INDEX_DESC(apsa,ar_payment_schedules_n1)
trx_date FROM ar_payment_schedules_all apsa
WHERE apsa.trx_date > sysdate - 7
ORDER BY apsa.trx_date DESC


PLAN
SELECT STATEMENT, GOAL = RULE
INDEX RANGE SCAN DESCENDING AR_PAYMENT_SCHEDULES_N1


Merging indexes (AND_EQUAL)
Sometimes adding filter conditions can result in the using of merged indexes which can greatly increase the speed of a query, even if the condition seems irrelevant.
Original
SELECT * FROM mtl_system_items msi
WHERE inventory_item_id > 50000 AND
organization_id = 1 AND
container_item_flag = 'N'
and segment1 like 'A%'


PLAN
SELECT STATEMENT, GOAL = RULE
TABLE ACCESS BY TABLE ROWID MTL_SYSTEM_ITEMS
INDEX RANGE SCAN CUX_XIAO_MTL_SYSTEM_ITEMS_N1

Result: 17 Rows, 74.957 secs*

Modified
SELECT * FROM mtl_system_items msi
WHERE inventory_item_id > 50000 AND
organization_id = 1 AND
item_type = 'STL' AND
container_item_flag = 'N'
AND segment1 like 'A%'


PLAN
SELECT STATEMENT, GOAL = RULE
TABLE ACCESS BY TABLE ROWID MTL_SYSTEM_ITEMS
AND-EQUAL
INDEX RANGE SCAN CUX_MTL_SYSTEM_ITEMS_N1
INDEX RANGE SCAN CUX_XIAO_MTL_SYSTEM_ITEMS_N1


Result: 17 Rows, 2.784 secs*

Results are dependant on server activity and results may differ with different servers and different workloads.


BAD SQL
Many speed problems are caused by bad SQL statements is not related to how the optimizer sets the execution plan. A badly written SQL will still be bad, even when you optimized them with hints. There main things to check for in debugging speed problems are as follows:
Are all the tables joined? Make sure all the tables are joined, and joined with the best fields to eliminate the most records.
Tables joined in proper order? Generally joined from parent to child.
Are all tables used? Make sure the table is used, but be careful as some tables are used for filtering.
Are there easier or faster ways to join the tables? Find the join path to a table using the least number of join conditions.

What is wrong with this statement?

select sha.org_id,
sha.packing_instructions,
sha.purchase_order_num,
sha.header_id,
so.name||'-'||sha.order_number,
sha.attribute2 picture,
sha.attribute15 invoceremark,
sha.attribute5 memo,
sha.attribute10 dan,
sha.attribute12 hkorder,
decode(sha.warehouse_id,1,'DG',4,'HY',3,'GZ') orga,
sha.warehouse_id warehouse,
decode(sha.attribute3,'I',' ','M',' ','U',' ','DI',' ','DM',' ','DU',' ','D',' ','S',' ','N',' ') la,
decode(sha.attribute4,'I',' ','M',' ','U',' ','DI',' ','DM',' ','DU',' ','D',' ','S',' ','N',' ') lo,
sla.schedule_date,
sla.creation_date s1_date,
sla.schedule_date,
sla.ordered_quantity allquantity,
decode(sla.attribute5,'I',' ','O',' ') water,
rsua.location||'-'||raa.address1,
rt.attribute1 route1,
msi.segment1,
msi.description,
fu.description,
he.full_name
from so_headers_all sha,
so_lines_all sla,
ar_customers ac,
fnd_user fu,
ra_site_uses_all rsua,
ra_addresses_all raa,
ra_site_uses_all rsua1,
ra_addresses_all raa1,
ra_territories rt,
mtl_system_items msi,
so_order_types_all so,
fnd_descr_flex_contexts fdfc,
hr_employees he
where sha.header_id=sla.header_id
and sha.customer_id=ac.customer_id
and sha.org_id=so.org_id
and sha.created_by=fu.user_id
and sla.inventory_item_id=msi.inventory_item_id
and sla.option_flag='N'
and sha.ship_to_site_use_id=rsua1.site_use_id(+)
and sha.invoice_to_site_use_id=rsua.site_use_id(+)
and rsua.address_id=raa.address_id
and rsua1.address_id=raa1.address_id
and rsua1.territory_id=rt.territory_id(+)
and sha.order_type_id=so.order_type_id
and sha.attribute1=he.employee_id(+)
and sla.warehouse_id=msi.organization_id
and fdfc.application_id=300
and fdfc.descriptive_flexfield_name='SO_HEADERS'
and msi.segment1 not like 'G%'
and sha.org_id=:p_org_id
and sha.order_type_id=:p_order_type_id
and sha.order_number between :p_order_number_lo and :p_order_number_hi
and sha.warehouse_id=nvl(:p_warehouse_id,sha.warehouse_id)
and sha.created_by=nvl(:p_created_by,sha.created_by)
and sha.attribute10=nvl(:p_attribute10,sha.attribute10)
order by sha.order_number

Notice
ar_customers ac,
ra_addresses_all raa1,
Both these tables are linked but are not used. The table and the joins associated with these tables can be safely removed without affecting the results.
Also the table fnd_descr_flex_contexts(fdfc) uses filter conditions but in not linked in any way. This is a bug and we should have added
and fdfc.descriptive_flex_context_code='M'
To the SQL statement

CHECK SQL FIRST!

Use of Nested loops
Nested loops out performs all other join methods when there are a number of large tables which are joined to narrow down the number of records. In the following example you will see that the optimizer opted to use HASH and MERGE JOINS, It has been modified to return one row.
Original statement


select oof.organization_code||'HI'|| RCT.TRX_NUMBER TRX_NUMBER11,
ra.address_id, rc.customer_id, RCT.SET_OF_BOOKS_ID SOB_ID, RSU.LOCATION,
SLA1.SELLING_PRICE*(SLA1.ordered_quantity-nvl(sla1.cancelled_quantity,0)) AMOUNT_TEMP,
RCT.INVOICE_CURRENCY_CODE CURRENCY_CODE, RCT.CREATION_DATE, RCT.CUSTOMER_TRX_ID,
RC.CUSTOMER_NAME, RC.CUSTOMER_NUMBER, RCT.WAYBILL_NUMBER, RCT.PURCHASE_ORDER,
RA.ADDRESS1, ra.ADDRESS2, ra.ADDRESS3, ra.ADDRESS4,
RCT.TRX_NUMBER, RCT.TRX_DATE,
decode(rt.name,' ',rt.name, RT.NAME||' ') TERM_NAME,
RCTL.SALES_ORDER, MSI.ATTRIBUTE4 DESCRIPTION_INTERFACE,
rctl.attribute_category, RCTL.ATTRIBUTE1, RCTL.ATTRIBUTE2, RCTL.ATTRIBUTE3,
rctl.attribute4||' ' DESCRIPTION , rctl.attribute4 STL_NUM,
(SLA1.ordered_quantity-nvl(sla1.cancelled_quantity,0))/1000 quantity_invoiced,
sla1.LIST_PRICE*1000 unit_selling_price,
SLA1.SELLING_PRICE*1000 BO_PRICE, RCTL.EXTENDED_AMOUNT,
sum(SPA.PERCENT) PERCENT, RCTL.LINE_NUMBER,
sla.original_system_line_reference so_line_id, SHA.ORDER_NUMBER,
DECODE(LENGTH(RCTL.INTERFACE_LINE_ATTRIBUTE2),4,SUBSTR(RCTL.INTERFACE_LINE_ATTRIBUTE2,1,4),7,SUBSTR(RCTL.INTERFACE_LINE_ATTRIBUTE2,4,7),8,SUBSTR(RCTL.INTERFACE_LINE_ATTRIBUTE2,5,8),RCTL.INTERFACE_LINE_ATTRIBUTE2)||'-'||RCTL.SALES_ORDER||'-'||RCT.ATTRIBUTE10 SHIP_NO,
SPA.HEADER_ID
from
RA_CUSTOMER_TRX_ALL RCT, RA_CUSTOMER_TRX_LINES_ALL RCTL,
RA_CUSTOMERS RC, RA_SITE_USES_ALL RSU, RA_ADDRESSES_ALL RA,
RA_TERMS RT, MTL_SYSTEM_ITEMS MSI, org_organization_definitions oof,
SO_PRICE_ADJUSTMENTS SPA, so_LINEs_all sla,
so_LINEs_all sla1, SO_HEADERS_ALL SHA
where
RCT.CUSTOMER_TRX_ID=RCTL.CUSTOMER_TRX_ID(+)
AND RCT.bill_TO_CUSTOMER_ID=RC.CUSTOMER_ID(+)
AND RCT.bill_TO_SITE_USE_ID=RSU.SITE_USE_ID(+)
AND RSU.ADDRESS_ID=RA.ADDRESS_ID(+)
AND RCT.TERM_ID=RT.TERM_ID(+)
AND rct.org_id=oof.organization_id(+)
AND RCTL.INTERFACE_LINE_ATTRIBUTE2 LIKE '%051'
AND RCTL.INTERFACE_LINE_ATTRIBUTE6=SPA.LINE_ID(+)
and RCTL.INTERFACE_LINE_ATTRIBUTE6=sla.line_id(+)
AND nvl(SLA.original_system_LINE_reference,sla.line_id)=SLA1.LINE_ID(+)
AND SLA1.HEADER_ID=SHA.HEADER_ID(+)
AND RCTL.INVENTORY_ITEM_ID=MSI.INVENTORY_ITEM_ID
AND RCT.ORG_ID=MSI.ORGANIZATION_ID
and rctl.line_type = 'LINE'
and rct.trx_number='10003789'
AND RCT.org_ID=5
and RC.CUSTOMER_NUMBER='H188'
and rctl.description not like '% %' and rctl.description not like '% %'--AND --NVL(RSU.ATTRIBUTE1,RCT.INVOICE_CURRENCY_CODE)=NVL(:P_CURRENCY_CODE,GSOB.CURRENCY_CODE)
GROUP BY
oof.organization_code||'HI'|| RCT.TRX_NUMBER,
ra.address_id,
rc.customer_id,
RCT.SET_OF_BOOKS_ID,
RSU.LOCATION,
SLA1.SELLING_PRICE*(SLA1.ordered_quantity-nvl(sla1.cancelled_quantity,0)),
RCT.INVOICE_CURRENCY_CODE,
RCT.CREATION_DATE,
RCT.CUSTOMER_TRX_ID,
RC.CUSTOMER_NAME,
RC.CUSTOMER_NUMBER,
RCT.WAYBILL_NUMBER,
RCT.PURCHASE_ORDER,
RA.ADDRESS1,ra.ADDRESS2,ra.ADDRESS3,ra.ADDRESS4 ,
RCT.TRX_NUMBER,
RCT.TRX_DATE,
decode(rt.name,' ',rt.name, RT.NAME||' '),
RCTL.SALES_ORDER,
MSI.ATTRIBUTE4,
rctl.attribute_category,
RCTL.ATTRIBUTE1,
RCTL.ATTRIBUTE2,
RCTL.ATTRIBUTE3,
rctl.attribute4||' ',
rctl.attribute4,
(SLA1.ordered_quantity-nvl(sla1.cancelled_quantity,0))/1000,
sla1.LIST_PRICE*1000,
SLA1.SELLING_PRICE*1000,
RCTL.EXTENDED_AMOUNT,
RCTL.LINE_NUMBER,
sla.original_system_line_reference,
SHA.ORDER_NUMBER,
DECODE(LENGTH(RCTL.INTERFACE_LINE_ATTRIBUTE2),4,SUBSTR(RCTL.INTERFACE_LINE_ATTRIBUTE2,1,4),7,SUBSTR(RCTL.INTERFACE_LINE_ATTRIBUTE2,4,7),8,SUBSTR(RCTL.INTERFACE_LINE_ATTRIBUTE2,5,8),RCTL.INTERFACE_LINE_ATTRIBUTE2)||'-'||RCTL.SALES_ORDER||'-'||RCT.ATTRIBUTE10,
SPA.HEADER_ID
ORDER BY RCT.TRX_NUMBER



PLAN (for STAR)
SELECT STATEMENT, GOAL = RULE
SORT GROUP BY
HASH JOIN OUTER
HASH JOIN OUTER
NESTED LOOPS OUTER
NESTED LOOPS OUTER
HASH JOIN
TABLE ACCESS BY INDEX ROWID MTL_SYSTEM_ITEMS
INDEX RANGE SCAN MTL_SYSTEM_ITEMS_N1
HASH OUTER JOIN
NESTED LOOPS OUTER
HASH JOIN
TABLE ACCESS FULL RA_CUSTOMER_TRX_LINES_ALL
NESTED LOOPS OUTER
NESTED LOOPS
TABLE ACCESS BY INDEX ROWID RA_CUSTOMERS
INDEX RANGE SCAN RA_CUSTOMERS_U3
TABLE ACCESS BY INDEX ROWID RA_CUSTOMER_TRX_ALL
INDEX RANGE SCAN RA_CUSTOMER_TRX_N11
VIEW ORG_ORGANIZATION_DEFINITIONS
HASH JOIN
TABLE ACCESS FULL GL_SETS_OF_BOOKS
MERGE JOIN CARTESIAN
HASH JOIN
HASH JOIN
TABLE ACCESS FULL HR_ORGANIZATION_INFORMATION
NESTED LOOP
TABLE ACCESS FULL MTL_PARAMETERS
INDEX UNIQUE SCAN HR_ORGANIZATION_UNITS_PK
TABLE ACCESS FULL HR_ORGANIZATION_INFORMATION
SORT JOIN
TABLE ACCESS FULL FND_PRODUCT_GROUPS
TABLE ACCESS BY ROWID RA_SITE_USES_ALL
INDEX UNIQUE SCAN RA_SITE_USES_U1
TABLE ACCESS FULL RA_TERMS
TABLE ACCESS BY INDEX ROWID RA_ADDRESSES_ALL
INDEX UNIQUE SCAN RA_ADDRESSES_U1
TABLE ACCESS BY INDEX ROWID SO_LINES_ALL
INDEX UNIQUE SCAN SO_LINES_U1
TABLE ACCESS BY INDEX ROWID SO_LINES_ALL
INDEX UNIQUE SCAN SO_LINES_U1
TABLE ACCESS FULL SO_HEADERS_ALL
TABLE ACCESS FULL SO_PRICE_ADJUSTMENTS


Execution time (using --+ORDERED): 91.795 secs*
Execution time (using --+STAR): 59.137 secs*

Modified
All we added was to force the optimizer to use nested loops (which made a large difference), and hinted a few indexes (which made slight differences)
select --+USE_NL INDEX (sha,so_headers_u1) INDEX (rctl,ra_customer_trx_lines_n2)
etc...


PLAN
SELECT STATEMENT, GOAL = RULE
SORT GROUP BY
MERGE JOIN OUTER
SORT JOIN
NESTED LOOPS OUTER
NESTED LOOPS OUTER
NESTED LOOPS OUTER
NESTED LOOPS OUTER
FILTER
NESTED LOOPS OUTER
NESTED LOOPS
FILTER
NESTED LOOPS OUTER
NESTED LOOPS OUTER
NESTED LOOPS OUTER
NESTED LOOPS OUTER
TABLE ACCESS BY INDEX ROWID RA_CUSTOMER_TRX_ALL
INDEX RANGE SCAN RA_CUSTOMER_TRX_N1
TABLE ACCESS BY INDEX ROWID RA_TERMS
INDEX UNIQUE SCAN RA_TERMS_U1
TABLE ACCESS BY INDEX ROWID RA_SITE_USES_ALL
INDEX UNIQUE SCAN RA_SITE_USES_U1
TABLE ACCESS BY INDEX ROWID RA_ADDRESSES_ALL
INDEX UNIQUE SCAN RA_ADDRESSES_U1
TABLE ACCESS BY INDEX ROWID RA_CUSTOMERS
INDEX UNIQUE SCAN RA_CUSTOMERS_U1
TABLE ACCESS BY INDEX ROWID MTL_SYSTEM_ITEMS
INDEX RANGE SCAN MTL_SYSTEM_ITEMS_N4
TABLE ACCESS BY INDEX ROWID RA_CUSTOMER_TRX_LINES_ALL
INDEX RANGE SCAN RA_CUSTOMER_TRX_LINES_N2
TABLE ACCESS BY INDEX ROWID SO_LINES_ALL
INDEX UNIQUE SCAN SO_LINES_U1
TABLE ACCESS BY INDEX ROWID SO_LINES_ALL
INDEX UNIQUE SCAN SO_LINES_U1
TABLE ACCESS BY INDEX ROWID SO_HEADERS_ALL
INDEX UNIQUE SCAN SO_HEADERS_U1
TABLE ACCESS BY INDEX ROWID SO_PRICE_ADJUSTMENTS
INDEX RANGE SCAN SO_PRICE_ADJUSTMENTS_N2
SORT JOIN
VIEW
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
MERGE JOIN
SORT JOIN
NESTED LOOPS
TABLE ACCESS FULL FND_PRODUCT_GROUPS
TABLE ACCESS FULL GL_SETS_OF_BOOKS
SORT JOIN
TABLE ACCESS FULL HR_ORGANIZATION_INFORMATION
INDEX UNIQUE SCAN HR_ORGANIZATION_UNITS_PK
TABLE ACCESS BY INDEX ROWID MTL_PARAMETERS
INDEX UNIQUE SCAN MTL_PARAMETERS_U1
TABLE ACCESS BY INDEX ROWID HR_ORGANIZATION_INFORMATION
INDEX RANGE SCAN HR_ORGANIZATION_INFORMATION_FK2


Execution time : 4.958 secs*

Final notes

The skill of optimization is not the knowledge of how it is done. This document can only provide the details of what can be done. The real skill of optimization is experience, to know when to use what to achieve the desired goal.
All optimizations depend on the data in the tables and the index available. As you seen above sometimes a what seems less efficient method is actually better, e.g. using a full table scan instead of the index, and splitting a statement to uses UNION ALL to force the optimizer to do different things for different parameters. In the end it is up to the developer to produce the best method to achieved the desired goal and not the optimizer itself.



Site Sponsors