Home » RDBMS Server » Performance Tuning » Query tuning (Oracle,9.0.2.0.5,Sunsolaris)
Query tuning [message #470243] Mon, 09 August 2010 07:05 Go to next message
sathik
Messages: 196
Registered: August 2009
Location: INDIA
Senior Member

Can anybody help me to reduce the cost of below query?

SQL> explain plan for
  2  select identity "VOIP_NUMBER",bbvoice_fusion_works.get_status_fusion_works(si.id,si.status,si.customer_id) "STATUS",
service_id "SERVICE_ID",customer_id "CUSTOMER_ID" from service_instances si where si.service_id in (18,25,26,27,29)
and identity is not null;  3    4

Explained.

SQL> select * from table (dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------
| Id  | Operation            |  Name              | Rows  | Bytes | Cost  |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |                    |   527K|    17M| 11173 |
|*  1 |  TABLE ACCESS FULL   | SERVICE_INSTANCES  |   527K|    17M| 11173 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(("SI"."SERVICE_ID"=18 OR "SI"."SERVICE_ID"=25 OR
              "SI"."SERVICE_ID"=26 OR "SI"."SERVICE_ID"=27 OR "SI"."SERVICE_ID"=29) AND
              "SI"."IDENTITY" IS NOT NULL)


Index_details:
==============

INDEX_NAME                     COLUMN_NAME
------------------------------ ---------------------------------------------
SI_EMAIL_I                     EMAIL_ADDRESS
ORD_MODIFY_IDEN_I              ORDER_MODIFY_IDENTIFIER
ORD_MODIFY_STAT_I              ORDER_MODIFY_STATUS
INST_PK                        ID
INST_CS_I                      CUSTOMER_ID
INST_CS_I                      SERVICE_ID
SI_CREATED_I                   CREATED
SI_UPDATED_I                   UPDATED
SI_SERV_ID                     SERVICE_ID
SI_STATUS_ID                   STATUS
SI_IDENTITY_I                  IDENTITY
Re: Query tuning [message #470246 is a reply to message #470243] Mon, 09 August 2010 07:10 Go to previous messageGo to next message
cookiemonster
Messages: 13921
Registered: September 2008
Location: Rainy Manchester
Senior Member
How many rows does the query return?
How many rows in the table?
Re: Query tuning [message #470248 is a reply to message #470246] Mon, 09 August 2010 07:16 Go to previous messageGo to next message
sathik
Messages: 196
Registered: August 2009
Location: INDIA
Senior Member
SQL> select count(*) from service_instances;

COUNT(*)
----------
1633111

From the explain plan, we can see it returns 527k rows.
Re: Query tuning [message #470249 is a reply to message #470248] Mon, 09 August 2010 07:26 Go to previous messageGo to next message
Roachcoach
Messages: 1576
Registered: May 2010
Location: UK
Senior Member
How long does it take? I presume you want to reduce the time rather than the 'cost'.

What options are available to you to tune? I.e. SQL only or can you play with the indexing etc

[Updated on: Mon, 09 August 2010 07:27]

Report message to a moderator

Re: Query tuning [message #470251 is a reply to message #470248] Mon, 09 August 2010 07:34 Go to previous messageGo to next message
sathik
Messages: 196
Registered: August 2009
Location: INDIA
Senior Member

The below package that we are using inside the query.

SQL> select text from user_source where name='BBVOICE_FUSION_WORKS';

TEXT
----------------------------------------------------------------------------------------------------------------------------------------------------
PACKAGE bbvoice_fusion_works IS

   FUNCTION get_status_fusion_works(inst_id service_instances.id%TYPE
                                   ,status  service_instances.status%TYPE
                                   ,cust_id service_instances.customer_id%TYPE)
      RETURN VARCHAR2;
END bbvoice_fusion_works;
PACKAGE BODY bbvoice_fusion_works IS

   v_pk_name CONSTANT VARCHAR2(240) := 'bbvoice_fusion_works';

   FUNCTION get_status_fusion_works(inst_id service_instances.id%TYPE
                                   ,status  service_instances.status%TYPE
                                   ,cust_id service_instances.customer_id%TYPE)
      RETURN VARCHAR2 IS

   BEGIN
      IF (bbvoice_services.get_parameter_value(bbvoice_service.get_instanceid(inst_id
                                                                             ,'0')
                                              ,'isTestAccount') = 'Y') THEN
         RETURN 'test';
      ELSIF (bbvoice_services.get_parameter_value(inst_id
                                                 ,'isExportedNumber') = 'Y') THEN
         RETURN 'exported';
      ELSIF (bbvoice_services.get_parameter_value(inst_id
                                                 ,'import_number_hdt') = 'Y') THEN
         RETURN 'imported';
      ELSIF (status IN
            ('new',
             'order_placed',
             'order_placed_voip',
             'config_requested',
             'config_requested_voip',
             'config_failed_voip',
             'order_failed_voip',
             'config_failed',
             'config_complete',
             'exchange_complete')) THEN
         RETURN 'new';
      ELSIF (status IN
            ('active',
             'modify_placed',
             'modify',
             'modify_failed',
             'exchange_complete_voip')) THEN
         RETURN 'active';
      ELSIF (status IN
            ('cease_placed',
             'ceased',
             'delete_complete',
             'suspend_requested',
             'delete_requested',
             'delete_failed',
             'resume_requested',
             'cease_requested',
             'cease_failed',
             'suspended',
             'parked',
             'wait_wls_response')) THEN
         RETURN 'suspended';
      ELSE
         RETURN 'active';
      END IF;
      RETURN 'active';
   END get_status_fusion_works;

END bbvoice_fusion_works;
Re: Query tuning [message #470253 is a reply to message #470251] Mon, 09 August 2010 07:37 Go to previous messageGo to next message
sathik
Messages: 196
Registered: August 2009
Location: INDIA
Senior Member
Yes I want to reduce the execution time of this query.

Basically we are using this query in a meterialized view. So it is taking 4.30 hours approximately for a complete refresh.
Some more info regarding that meterialized view is given below.

SQL> select LAST_REFRESH_DATE,REFRESH_METHOD,SUMMARY,FULLREFRESHTIM,INCREFRESHTIM,CONTAINS_VIEWS,UNUSABLE,RESTRICTED_SYNTAX,INC_REFRESHABLE,KNOWN_STALE,
  2  INVALID,QUERY_LEN,QUERY,REVISION from user_mview_analysis where MVIEW_NAME='BBV_FUSIONWORKS_MAT_VIEW';

LAST_REFRESH_DAT REFRESH_ S FULLREFRESHTIM INCREFRESHTIM C you are I K I  QUERY_LEN QUERY                                                    REVISION
---------------- -------- - -------------- ------------- - - - - - - ---------- ------------------------------------------------------ ----------
19:00 08/08/2010 FORCE    N          15741             0 N N N N Y N        256 select identity "VOIP_NUMBER"                                  22
                                                                                ,bbvoice_fusion_works.get_status_fusion_works(si.id,si
                                                                                .status,si.customer_id) "STATUS"
                                                                                ,service_id "SERVICE_ID"
                                                                                ,customer_id "CUSTOMER_ID"
                                                                                from service_instances si
                                                                                where si.service_id in (18,25,26,27)
                                                                                and identity is not null

[Updated on: Mon, 09 August 2010 07:39]

Report message to a moderator

Re: Query tuning [message #470256 is a reply to message #470249] Mon, 09 August 2010 07:45 Go to previous messageGo to next message
sathik
Messages: 196
Registered: August 2009
Location: INDIA
Senior Member
I have created a copy of service instances table called ser.So I can apply any kind of changes in that table.



Re: Query tuning [message #470259 is a reply to message #470256] Mon, 09 August 2010 07:53 Go to previous messageGo to next message
Roachcoach
Messages: 1576
Registered: May 2010
Location: UK
Senior Member
How fast is the select statement if you chop the PL/SQL function out?
Re: Query tuning [message #470275 is a reply to message #470248] Mon, 09 August 2010 08:19 Go to previous messageGo to next message
cookiemonster
Messages: 13921
Registered: September 2008
Location: Rainy Manchester
Senior Member
sathik wrote on Mon, 09 August 2010 13:16
SQL> select count(*) from service_instances;

COUNT(*)
----------
1633111

From the explain plan, we can see it returns 527k rows.


No we can see that oracle thinks it's going to return 527k rows. It could be wrong.
So issue a query to get the exact count.

Assuming it's right you're selecting approx 32% of the table - in which case oracle will almost certainly have to use a full table scan as that'll be more efficient than using indexes.
Re: Query tuning [message #470347 is a reply to message #470275] Mon, 09 August 2010 10:59 Go to previous messageGo to next message
sathik
Messages: 196
Registered: August 2009
Location: INDIA
Senior Member

SQL> select count(*) from service_instances;

  COUNT(*)
----------
   1632815

SQL> select count(*) from service_instances si where si.service_id in (18,25,26,27,29) and identity is not null;

  COUNT(*)
----------
    150274


As per this count, the query is retriving 10% of rows. in this case, will oracle go full table scan or index scan?
Re: Query tuning [message #470348 is a reply to message #470259] Mon, 09 August 2010 11:01 Go to previous messageGo to next message
sathik
Messages: 196
Registered: August 2009
Location: INDIA
Senior Member
Explain plan without PL/SQL function is given below. there is no change in the cost.

SQL> explain plan for
  2  select identity "VOIP_NUMBER",service_id "SERVICE_ID",customer_id "CUSTOMER_ID" from service_instances si
  3  where si.service_id in (18,25,26,27,29) and identity is not null;

Explained.

SQL> select * from table (dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------
| Id  | Operation            |  Name              | Rows  | Bytes | Cost  |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |                    |   527K|    10M| 11173 |
|*  1 |  TABLE ACCESS FULL   | SERVICE_INSTANCES  |   527K|    10M| 11173 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(("SI"."SERVICE_ID"=18 OR "SI"."SERVICE_ID"=25 OR
              "SI"."SERVICE_ID"=26 OR "SI"."SERVICE_ID"=27 OR "SI"."SERVICE_ID"=29) AND
              "SI"."IDENTITY" IS NOT NULL)



Re: Query tuning [message #470352 is a reply to message #470348] Mon, 09 August 2010 11:17 Go to previous messageGo to next message
Roachcoach
Messages: 1576
Registered: May 2010
Location: UK
Senior Member
sathik wrote on Mon, 09 August 2010 17:01
Explain plan without PL/SQL function is given below. there is no change in the cost.

SQL> explain plan for
  2  select identity "VOIP_NUMBER",service_id "SERVICE_ID",customer_id "CUSTOMER_ID" from service_instances si
  3  where si.service_id in (18,25,26,27,29) and identity is not null;

Explained.

SQL> select * from table (dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------
| Id  | Operation            |  Name              | Rows  | Bytes | Cost  |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |                    |   527K|    10M| 11173 |
|*  1 |  TABLE ACCESS FULL   | SERVICE_INSTANCES  |   527K|    10M| 11173 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(("SI"."SERVICE_ID"=18 OR "SI"."SERVICE_ID"=25 OR
              "SI"."SERVICE_ID"=26 OR "SI"."SERVICE_ID"=27 OR "SI"."SERVICE_ID"=29) AND
              "SI"."IDENTITY" IS NOT NULL)





I wasnt expecting a cost change, I was expecting a real time improvement.

Cost isnt what you think it ism its an internal Oracle metric. I suspect that if the P/LSQL block was redone as a series of case statements it may well be faster due to less context switching (and better information feeding the optimizer), but first we should ascertain the run time without it as opposed to the "cost" change.

Edit: Although its odd that its row count estimate is so out vs reality, are the stats ok?

[Updated on: Mon, 09 August 2010 11:28]

Report message to a moderator

Re: Query tuning [message #470356 is a reply to message #470352] Mon, 09 August 2010 11:28 Go to previous messageGo to next message
cookiemonster
Messages: 13921
Registered: September 2008
Location: Rainy Manchester
Senior Member
And cost never factors in function calls in the select part.

If you're selecting 10% of the rows and oracle thinks your selecting 33% of the rows then it's doing a bad estimate.
An index on (SERVICE_ID, IDENTITY) might help.

However I suspect that the function is the bigger problem - So do as Roachcoach asks and see how long it takes to run the SQL without it.
Re: Query tuning [message #470368 is a reply to message #470352] Mon, 09 August 2010 12:11 Go to previous messageGo to next message
sathik
Messages: 196
Registered: August 2009
Location: INDIA
Senior Member
Yes. You are correct.

The run time for the query (without PL/SQL) is 06:07 minutes. And it fetched 150287 rows.

But if run the query with PL/SQL function, it is taking 1:11 hours to fetch 47580 rows. Really it is a big difference.


Now can you pls suggest some idea, how can I reduce the runtime of the query,when I include PL/SQL function?

Re: Query tuning [message #470370 is a reply to message #470368] Mon, 09 August 2010 12:14 Go to previous messageGo to next message
cookiemonster
Messages: 13921
Registered: September 2008
Location: Rainy Manchester
Senior Member
We would need to know the code for: bbvoice_services.get_parameter_value and bbvoice_service.get_instanceid
Re: Query tuning [message #470384 is a reply to message #470368] Mon, 09 August 2010 13:30 Go to previous messageGo to next message
Roachcoach
Messages: 1576
Registered: May 2010
Location: UK
Senior Member
sathik wrote on Mon, 09 August 2010 18:11
Yes. You are correct.

The run time for the query (without PL/SQL) is 06:07 minutes. And it fetched 150287 rows.

But if run the query with PL/SQL function, it is taking 1:11 hours to fetch 47580 rows. Really it is a big difference.


Now can you pls suggest some idea, how can I reduce the runtime of the query,when I include PL/SQL function?



Why is the row count dimishing when you add the function in when I dont see it as a part of your WHERE clause in the first post?
Re: Query tuning [message #470598 is a reply to message #470384] Tue, 10 August 2010 05:04 Go to previous messageGo to next message
sathik
Messages: 196
Registered: August 2009
Location: INDIA
Senior Member

evertime an insert query is firing againist this table.Thatswhy there are some difference in the count.

Please let me know how can I reduce the runtime of PL/SQL function?
Re: Query tuning [message #470603 is a reply to message #470370] Tue, 10 August 2010 05:14 Go to previous messageGo to next message
cookiemonster
Messages: 13921
Registered: September 2008
Location: Rainy Manchester
Senior Member
cookiemonster wrote on Mon, 09 August 2010 18:14
We would need to know the code for: bbvoice_services.get_parameter_value and bbvoice_service.get_instanceid

Re: Query tuning [message #470625 is a reply to message #470603] Tue, 10 August 2010 06:15 Go to previous messageGo to next message
sathik
Messages: 196
Registered: August 2009
Location: INDIA
Senior Member

Hi,

Please find the attachement for the bbvoice_services package.
Re: Query tuning [message #470634 is a reply to message #470625] Tue, 10 August 2010 06:27 Go to previous messageGo to next message
cookiemonster
Messages: 13921
Registered: September 2008
Location: Rainy Manchester
Senior Member
Next time just post the relevant bits of code directly:
  FUNCTION get_parameter_value(v_iid  IN INTEGER                                                                                                                                                       
                               ,v_name IN VARCHAR2)                                                                                                                                                     
      RETURN VARCHAR2 IS                                                                                                                                                                                
      p_rec tactoss_service.par_rectype;                                                                                                                                                                
   BEGIN                                                                                                                                                                                                
      p_rec := tactoss_service.get_parameter(v_iid                                                                                                                                                      
                                            ,v_name);                                                                                                                                                   
      RETURN p_rec.VALUE;                                                                                                                                                                               
   EXCEPTION                                                                                                                                                                                            
      WHEN tactoss_service.parameter_not_set THEN                                                                                                                                                       
         RETURN NULL;                                                                                                                                                                                   
         /****** bug fix 4325 start*****/                                                                                                                                                               
      WHEN OTHERS THEN                                                                                                                                                                                  
         dbfl_error.raise_error('E'                                                                                                                                                                     
                               ,'Unhandled Exception:' ||                                                                                                                                               
                                SQLERRM                                                                                                                                                                 
                               ,pk_name ||                                                                                                                                                              
                                '.get_parameter_value');                                                                                                                                                
         RETURN NULL;                                                                                                                                                                                   
         /****** bug fix 4325 end*****/                                                                                                                                                                 
   END;                                                    


Which doesn't help at all really since all it returns is the result of another function call from a different package.
And get_instanceid isn't in that package.

I assume that those two functions at some point do a query on a table.
So you need to change your query to link directly to that table to get the same rows that the function returns.
You would then use a case statement to replicate the IF statements in get_status_fusion_works.

With the lack of info I really can't say more than that.
So give it a try and post back if you get stuck.
Re: Query tuning [message #470828 is a reply to message #470634] Wed, 11 August 2010 01:21 Go to previous message
sathik
Messages: 196
Registered: August 2009
Location: INDIA
Senior Member
Ok.I will check with my develoment team.
Thanks for your great help.

[Updated on: Wed, 11 August 2010 01:22]

Report message to a moderator

Previous Topic: Slow Update
Next Topic: how to get explain plan
Goto Forum:
  


Current Time: Tue Apr 30 12:01:00 CDT 2024