Avatar of Swadhin Ray
Swadhin Ray
Flag for United States of America asked on

SQL query taking time

Hello Experts,

I have the below SQL which is taking 12 sec to execute when attached to a web application:

SELECT org_entity_name
       ,org_entity_id
       ,org_hierarchy_name
       ,division
       ,area
       ,organization
   FROM ms_grc_parent_orgs mgpo
  WHERE EXISTS (SELECT 1
           FROM ms_flow_down_org
          WHERE org_entity_id = mgpo.org_entity_id
                AND user_name = 'E131094')
        AND org_hierarchy_name = 'Level 4 - Department';

Open in new window



Execution plan is as below:

				Plan hash value: 4043587597
 
---------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name               | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                    |     1 |   141 |   585   (1)| 00:00:08 |
|*  1 |  HASH JOIN SEMI              |                    |     1 |   141 |   585   (1)| 00:00:08 |
|*  2 |   TABLE ACCESS FULL          | MS_GRC_PARENT_ORGS |   161 | 20930 |     5   (0)| 00:00:01 |
|   3 |   TABLE ACCESS BY INDEX ROWID| MS_FLOW_DOWN_ORG   |  3524 | 38764 |   580   (1)| 00:00:07 |
|*  4 |    INDEX RANGE SCAN          | MFDO_USER_NAME_IDX |  3524 |       |    16   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - access("ORG_ENTITY_ID"="MGPO"."ORG_ENTITY_ID")
   2 - filter("ORG_HIERARCHY_NAME"='Level 4 - Department')
   4 - access("USER_NAME"='E131094')
 

Open in new window


Records present on the tables are as below:

select count(*) from ms_grc_parent_orgs;	 -- 263
			
select count(*) from ms_flow_down_org; -- 243177 

Open in new window


 indexes are present only on table ms_flow_down_org for columns :  ACTIVITY_NAME, ORG_ENTITY_ID, USER_ID, USER_NAME [No composite index present] but even index creation on "ms_grc_parent_orgs" table doesn't help.
No change in the plan or on time.

Please help on this.
Oracle Database

Avatar of undefined
Last Comment
Swadhin Ray

8/22/2022 - Mon
SOLUTION
Guy Hengel [angelIII / a3]

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
Swadhin Ray

ASKER
After creating the index the cost was reduced but the CPU % got increased :

create index  MGPO_ORG_HIERARCHY_NAME_IDX on MS_GRC_PARENT_ORGS(ORG_HIERARCHY_NAME);
create index  MFDO__OEI_USER_NAME_IDX on MS_FLOW_DOWN_ORG(ORG_ENTITY_ID,USER_NAME );

---OUTPUT 
index MGPO_ORG_HIERARCHY_NAME_IDX created.
index MFDO__OEI_USER_NAME_IDX created.

explain plan for
 SELECT org_entity_name
       ,org_entity_id
       ,org_hierarchy_name
       ,division
       ,area
       ,organization
   FROM ms_grc_parent_orgs mgpo
  WHERE EXISTS (SELECT 1
           FROM ms_flow_down_org
          WHERE org_entity_id = mgpo.org_entity_id
                AND user_name = 'E131094')
        AND org_hierarchy_name = 'Level 4 - Department';

select * from table(dbms_xplan.display);

Plan hash value: 1039081615
 
-------------------------------------------------------------------------------------------------
| Id  | Operation             | Name                    | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |                         |     1 |   141 |   229   (2)| 00:00:03 |
|*  1 |  HASH JOIN SEMI       |                         |     1 |   141 |   229   (2)| 00:00:03 |
|*  2 |   TABLE ACCESS FULL   | MS_GRC_PARENT_ORGS      |   161 | 20930 |     5   (0)| 00:00:01 |
|*  3 |   INDEX FAST FULL SCAN| MFDO__OEI_USER_NAME_IDX |  3524 | 38764 |   223   (1)| 00:00:03 |
-------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - access("ORG_ENTITY_ID"="MGPO"."ORG_ENTITY_ID")
   2 - filter("ORG_HIERARCHY_NAME"='Level 4 - Department')
   3 - filter("USER_NAME"='E131094')
 
Note
-----
   - 'PLAN_TABLE' is old version

ALTER INDEX MGPO_ORG_HIERARCHY_NAME_IDX
  REBUILD COMPUTE STATISTICS;

ALTER INDEX MFDO__OEI_USER_NAME_IDX
  REBUILD COMPUTE STATISTICS;	

Still the plan was same: 

Plan hash value: 1039081615
 
-------------------------------------------------------------------------------------------------
| Id  | Operation             | Name                    | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |                         |     1 |   141 |   229   (2)| 00:00:03 |
|*  1 |  HASH JOIN SEMI       |                         |     1 |   141 |   229   (2)| 00:00:03 |
|*  2 |   TABLE ACCESS FULL   | MS_GRC_PARENT_ORGS      |   161 | 20930 |     5   (0)| 00:00:01 |
|*  3 |   INDEX FAST FULL SCAN| MFDO__OEI_USER_NAME_IDX |  3524 | 38764 |   223   (1)| 00:00:03 |
-------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - access("ORG_ENTITY_ID"="MGPO"."ORG_ENTITY_ID")
   2 - filter("ORG_HIERARCHY_NAME"='Level 4 - Department')
   3 - filter("USER_NAME"='E131094')
 
Note
-----
   - 'PLAN_TABLE' is old version

Open in new window

Guy Hengel [angelIII / a3]

and the time of the actual query?
Swadhin Ray

ASKER
is taking around 9.5-10.5 Secs
Your help has saved me hundreds of hours of internet surfing.
fblack61
SOLUTION
slightwv (䄆 Netminder)

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
SOLUTION
Log in to continue reading
Log In
Sign up - Free for 7 days
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
johnsone

The FIRST_ROWS hint has nothing to do with the number of rows to be returned.  Essentially the default behavior of the CBO is what is the ALL_ROWS hint.  This tends toward full table scans.  A FIRST_ROWS hint tends toward nested loops.  The emphasis is on getting back the first rows the fastest.

Given the size of the tables, it doesn't look to me like you would ever get to use an index on the outer table.  What if you switched the order of the 2 columns in the MFDO__OEI_USER_NAME_IDX index?  That might get you an index range scan rather than a full scan.  That might save some time.
Alex [***Alex140181***]

The FIRST_ROWS hint has nothing to do with the number of rows to be returned.
That is not fully true, as shown here:

https://docs.oracle.com/cd/E11882_01/server.112/e41084/sql_elements006.htm#BABGCCFG

The FIRST_ROWS hint instructs Oracle to optimize an individual SQL statement for fast response, choosing the plan that returns the first n rows most efficiently. For integer, specify the number of rows to return.

So, again: Obviously this "integer" parameter is not optional. What does Oracle / the CBO do if you ommit this value?!
slightwv (䄆 Netminder)

>>I thought this hint needs a certain number of rows like: ?!?

Never knew about the number parameter.  I try to avoid hints and let the optimizer do its magic.  The number is optional.  Not sure what the benefit to specifying the number is.

You would just need to experiment to see any possible benefits.
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
Alex [***Alex140181***]

Never knew about the number parameter.  I try to avoid hints and let the optimizer do its magic.
I totally agree with you ;-)
But, nevertheless, if this parameter is optional then the official docs are wrong about this one...
johnsone

I never used the integer hint.  It is a optimizer path hint.  It tells the optimizer which join method to try to use.  ALL_ROWS will tend to use hash joins and FIRST_ROWS will tend to use nested loops.
Alex [***Alex140181***]

Got it:
https://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements006.htm

The FIRST_ROWS hint specified without an argument, which optimizes for the best plan to return the first single row, is retained for backward compatibility and plan stability only.

Obviously deprecated...
All of life is about relationships, and EE has made a viirtual community a real community. It lifts everyone's boat
William Peck
johnsone

We tend to not use hints.  The optimizer has gotten much better so we don't find that we need to use them that often.

FIRST_ROWS is a blanket hint, we tried not to use it.  Hinting the optimizer to use specific indexes was a much better way to go than using this hint.
slightwv (䄆 Netminder)

Getting way off topic.

I think the more important part of my post was:  AND rownum=1
ASKER CERTIFIED SOLUTION
Log in to continue reading
Log In
Sign up - Free for 7 days
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
Sean Stuber

>>> I have the below SQL which is taking 12 sec to execute when attached to a web application:


What is the execution time of the query by itself - without the web app?
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
Swadhin Ray

ASKER
after making the changes as suggested :

 SELECT org_entity_name
       ,org_entity_id
       ,org_hierarchy_name
       ,division
       ,area
       ,organization
   FROM ms_grc_parent_orgs mgpo
  WHERE EXISTS (SELECT /*+ OPT_PARAM('optimizer_dynamic_sampling' 6) */ 1
           FROM ms_flow_down_org
          WHERE org_entity_id = mgpo.org_entity_id
                AND user_name = 'E131094'
                and rownum =1)
        AND org_hierarchy_name = 'Level 4 - Department';

Open in new window


Now it is taking 0.7 sec
Sean Stuber

you should not need rownum=1 that's just a wasted step in the plan

the HASH JOIN SEMI was already doing the same thing (or should have anyway - that's what the "SEMI" means)

after your remove the rownum, get full plan with the predicate clauses
SOLUTION
Log in to continue reading
Log In
Sign up - Free for 7 days
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
Swadhin Ray

ASKER
This question was really a learning for me. Thanks a lot experts for all your comments.


Thanks,
Sloba
Experts Exchange is like having an extremely knowledgeable team sitting and waiting for your call. Couldn't do my job half as well as I do without it!
James Murphy
Swadhin Ray

ASKER
Awesome inputs provided on this question...