Home » RDBMS Server » Performance Tuning » reducing the parse-execution ration
reducing the parse-execution ration [message #460876] Tue, 15 June 2010 05:43 Go to next message
akilabaskaran
Messages: 29
Registered: May 2007
Location: chennai
Junior Member
Hi,

I have a procedure which has a select query with two 'Union All' used in it.

The structure of the query is as follows

select sum(col1) from (select count(distinct col1) col1
from a inner join b on
a.col2=b.col1
inner join c on c.col1 = b.col3
inner join d on d.col1 = c.col2
where ( (a.int_status_id =7)
OR ( (a.int_status_id = 6)
and (sysdate-a.date) =10))
and a.txn_type = 's'
union all
select count(distinct col1) col1
from a inner join b on
a.col2=b.col1
inner join c on c.col1 = b.col3
inner join d on d.col1 = c.col2
where ( (a.int_status_id =7)
OR ( (a.int_status_id = 6)
and (sysdate-a.date) =10))
and a.txn_type = 'x'
union all
select count(distinct col1) col1
from a where a.txn_type = 'Y')

my goal is to reduce the elapse time for this query and this is executed at least 10 each day.

When i rewrite the same query using 'With Clause' the disk read is increased.

While analyzing the explain plan i found parallel executions being taking place and because of it for each execution, the parse_call is 4

that is the parse calls are more than the number of executions.
I tried using the NO_Parallel hint but even then the explain plan uses parallel execution.

Kindly let me know what should i do to reduce the parse calls/avoid parallel execution.

Thanks,
Akilam.
Re: reducing the parse-execution ration [message #460886 is a reply to message #460876] Tue, 15 June 2010 06:36 Go to previous messageGo to next message
akilabaskaran
Messages: 29
Registered: May 2007
Location: chennai
Junior Member
Formatted the code

SELECT SUM(col1) 
FROM   (SELECT COUNT(DISTINCT col1) col1 
        FROM   a 
               inner join b 
                 ON a.col2 = b.col1 
               inner join c 
                 ON c.col1 = b.col3 
               inner join d 
                 ON d.col1 = c.col2 
        WHERE  ( ( a.int_status_id = 7 ) 
                  OR ( ( a.int_status_id = 6 ) 
                       AND ( SYSDATE - a.DATE ) = 10 ) ) 
               AND a.txn_type = 's' 
        UNION ALL 
        SELECT COUNT(DISTINCT col1) col1 
        FROM   a 
               inner join b 
                 ON a.col2 = b.col1 
               inner join c 
                 ON c.col1 = b.col3 
               inner join d 
                 ON d.col1 = c.col2 
        WHERE  ( ( a.int_status_id = 7 ) 
                  OR ( ( a.int_status_id = 6 ) 
                       AND ( SYSDATE - a.DATE ) = 10 ) ) 
               AND a.txn_type = 'x' 
        UNION ALL 
        SELECT COUNT(DISTINCT col1) col1 
        FROM   a 
        WHERE  a.txn_type = 'Y')  

[Updated on: Tue, 15 June 2010 06:49]

Report message to a moderator

Re: reducing the parse-execution ration [message #460894 is a reply to message #460886] Tue, 15 June 2010 07:08 Go to previous messageGo to next message
cookiemonster
Messages: 13922
Registered: September 2008
Location: Rainy Manchester
Senior Member
Is a.col1 unique?
And are you sure this bit is right:
AND ( SYSDATE - a.DATE ) = 10 

Since sysdate includes a time component that's going to struggle to find any matches, are you sure you shouldn't be using trunc in there?
Re: reducing the parse-execution ration [message #460896 is a reply to message #460894] Tue, 15 June 2010 07:16 Go to previous messageGo to next message
akilabaskaran
Messages: 29
Registered: May 2007
Location: chennai
Junior Member
yes col1 is unique and i actually use the below code for the date part

( (SYSDATE - a.date1) * 24 * 60) >= i_int_failed_timeout

here i_int_failed_timeout is the input parameter to the procedure
Re: reducing the parse-execution ration [message #460898 is a reply to message #460896] Tue, 15 June 2010 07:29 Go to previous messageGo to next message
cookiemonster
Messages: 13922
Registered: September 2008
Location: Rainy Manchester
Senior Member
In that case can't you rewrite it as:
SELECT SUM(col1) 
FROM   (SELECT COUNT(DISTINCT col1) col1 
        FROM   a 
               inner join b 
                 ON a.col2 = b.col1 
               inner join c 
                 ON c.col1 = b.col3 
               inner join d 
                 ON d.col1 = c.col2 
        WHERE  (a.int_status_id = 7  
                OR a.int_status_id = 6 AND ( SYSDATE - a.DATE ) = 10 ) 
        AND a.txn_type IN ('s', 'x')
        UNION ALL 
        SELECT COUNT(*) col1 
        FROM   a 
        WHERE  a.txn_type = 'Y')


Doesn't fix your parallel problem but should reduce the execution time anyway.
Re: reducing the parse-execution ration [message #460901 is a reply to message #460898] Tue, 15 June 2010 07:43 Go to previous messageGo to next message
akilabaskaran
Messages: 29
Registered: May 2007
Location: chennai
Junior Member
Hi,

I appreciate your effort and sorry for not posting the actual code . i have rwritten the complete code.

Kindly give me your suggestions for this code

SELECT SUM(col1) 
FROM   (SELECT COUNT(DISTINCT col1) col1 
              FROM   a inner join b  ON a.col2 = b.col1 
               inner join c     ON c.col1 = b.col3 
               inner join d   ON d.col1 = c.col2 
               WHERE  ( ( a.int_status_id = 7 ) 
                  OR ( ( a.int_status_id = 6 ) 
                    AND  ( (SYSDATE - a.date) * 24 * 60) >= 10))
                   AND a.txn_type = 's'
                   AND ( (c.status IN   ('ORDER TAKEN', 'AUTHORISE', 'AUTHORISING')
                    AND d.status = 'APPROVED')
                    OR c.status NOT IN ('ORDER TAKEN', 'AUTHORISE', 'AUTHORISING'))
                   and a.col7 is not null
        UNION ALL 
        SELECT COUNT(DISTINCT col1) col1 
        FROM   a  inner join b   ON a.col2 = b.col1 
                         inner join c  ON c.col1 = b.col3 
                         inner join d   ON d.col1 = c.col2 
         WHERE  ( ( a.int_status_id = 7 ) 
                  OR ( ( a.int_status_id = 6 ) and
                       ( (SYSDATE - a.date) * 24 * 60) >= 10))              
                        AND a.txn_type = 's' 
                    and d.status = 'APPROVED'
                   and a.col7 is null
        UNION ALL 
        SELECT COUNT(DISTINCT col1) col1 
        FROM   a 
        WHERE  a.txn_type = 'Y' ( a.int_status_id = 7 ) d  

[Updated on: Tue, 15 June 2010 07:45]

Report message to a moderator

Re: reducing the parse-execution ration [message #460904 is a reply to message #460901] Tue, 15 June 2010 07:50 Go to previous messageGo to next message
cookiemonster
Messages: 13922
Registered: September 2008
Location: Rainy Manchester
Senior Member
This bit is incomplete:
SELECT COUNT(DISTINCT col1) col1 
        FROM   a 
        WHERE  a.txn_type = 'Y' ( a.int_status_id = 7 ) d  

Re: reducing the parse-execution ration [message #460905 is a reply to message #460901] Tue, 15 June 2010 07:56 Go to previous messageGo to next message
akilabaskaran
Messages: 29
Registered: May 2007
Location: chennai
Junior Member
sorry it is

( a.int_status_id = 7 )) d .....


end of the sub query
Re: reducing the parse-execution ration [message #460906 is a reply to message #460905] Tue, 15 June 2010 07:59 Go to previous messageGo to next message
cookiemonster
Messages: 13922
Registered: September 2008
Location: Rainy Manchester
Senior Member
?
What sub query?
And what you've put doesn't appear to differ from what I quoted.
Re: reducing the parse-execution ration [message #460907 is a reply to message #460906] Tue, 15 June 2010 08:04 Go to previous messageGo to next message
akilabaskaran
Messages: 29
Registered: May 2007
Location: chennai
Junior Member
SELECT SUM(col1) 
FROM   (SELECT COUNT(DISTINCT col1) col1 
              FROM   a inner join b  ON a.col2 = b.col1 
               inner join c     ON c.col1 = b.col3 
               inner join d   ON d.col1 = c.col2 
               WHERE  ( ( a.int_status_id = 7 ) 
                  OR ( ( a.int_status_id = 6 ) 
                    AND  ( (SYSDATE - a.date) * 24 * 60) >= 10))
                   AND a.txn_type = 's'
                   AND ( (c.status IN   ('ORDER TAKEN', 'AUTHORISE', 'AUTHORISING')
                    AND d.status = 'APPROVED')
                    OR c.status NOT IN ('ORDER TAKEN', 'AUTHORISE', 'AUTHORISING'))
                   and a.col7 is not null
        UNION ALL 
        SELECT COUNT(DISTINCT col1) col1 
        FROM   a  inner join b   ON a.col2 = b.col1 
                         inner join c  ON c.col1 = b.col3 
                         inner join d   ON d.col1 = c.col2 
         WHERE  ( ( a.int_status_id = 7 ) 
                  OR ( ( a.int_status_id = 6 ) and
                       ( (SYSDATE - a.date) * 24 * 60) >= 10))              
                        AND a.txn_type = 's' 
                    and d.status = 'APPROVED'
                   and a.col7 is null
        UNION ALL 
        SELECT COUNT(DISTINCT col1) col1 
        FROM   a 
        WHERE  a.txn_type = 'Y' and a.int_status_id = 7 ) d  
Re: reducing the parse-execution ration [message #460912 is a reply to message #460907] Tue, 15 June 2010 08:39 Go to previous messageGo to next message
cookiemonster
Messages: 13922
Registered: September 2008
Location: Rainy Manchester
Senior Member
I'm not sure if you're trying to hide your table structure from me or simplify the code in attempt to make my life easier but either way your rewrites keep changing the meaning of the select so I can't meaningfully rewrite it.

For example your first version has a different value for txn_type in each of the 1st two selects (s and x).
Your later rewrites only have one value for txn_type in each of the 1st two selects (s).
That changes the meaning of the select.

If you want me, or anyone else here to have a go at it you need to copy and paste the original select in full and unaltered.

I can tell you the approach I was thinking of so you can have a go yourself:

Basically the first two selects can be combined into one. They're accessing the same tables, with the same joins and very similar where clauses.
The rows from each appear to be mutually exclusive so the COUNT(DISTINCT(col1)) will give the same result when they are combined.
You just need to OR the bits of the where clause that differ between the two.

Past that you can try replacing the joins to b, c and d with an exists sub-query, this may or may not help.
If you do do this then you can replace the COUNT(DISTINCT(col1)) with COUNT(*).


By the way - a select in the from clause isn't referred to as a sub-query, it's called an inline view.
Re: reducing the parse-execution ration [message #461467 is a reply to message #460912] Fri, 18 June 2010 03:30 Go to previous messageGo to next message
akilabaskaran
Messages: 29
Registered: May 2007
Location: chennai
Junior Member
hi,

Sorry for modifying my query these many times.
But i have followed your suggestions and it really have helped in my performance thanks.
Re: reducing the parse-execution ration [message #461474 is a reply to message #461467] Fri, 18 June 2010 03:59 Go to previous message
cookiemonster
Messages: 13922
Registered: September 2008
Location: Rainy Manchester
Senior Member
Thanks for letting us know.

Previous Topic: database fragmentation
Next Topic: to reduce the disk reads
Goto Forum:
  


Current Time: Sun May 12 18:47:08 CDT 2024