pg.ddx.io  pgsql-performance@postgresql.org mailing list archive  
help / color / mirror / Atom feed
Postgres8.0 Planner chooses WRONG plan.
5+ messages / 3 participants
[nested] [flat]

* Postgres8.0 Planner chooses WRONG plan.
@ 2006-01-11 15:03 Pallav Kalva <pkalva@livedatagroup.com>
  0 siblings, 0 replies; 5+ messages in thread

From: Pallav Kalva @ 2006-01-11 15:03 UTC (permalink / raw)
  To: pgsql-performance

Hi ,


    I am having problem optimizing this query, Postgres optimizer uses a 
plan which invloves seq-scan on a table. And when I choose a option to 
disable seq-scan it uses index-scan and obviously the query is much faster.
    All tables are daily vacummed and analyzed as per docs.

   Why cant postgres use index-scan ?


Postgres Version:8.0.2
Platform : Fedora

Here is the explain analyze output. Let me know if any more information 
is needed.  Can we make postgres use index scan for this query ?

Thanks!
Pallav.

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
explain analyze
 select * from provisioning.alerts where countystate = 'FL' and countyno 
= '099' and status = 'ACTIVE' ;

                                                                    
QUERY PLAN                                                               
--------------------------------------------------------------------------------------------------------------------------------------------------
 Nested Loop  (cost=3.45..15842.17 rows=1 width=125) (actual 
time=913.491..18992.009 rows=110 loops=1)
   ->  Nested Loop  (cost=3.45..15838.88 rows=1 width=86) (actual 
time=913.127..18958.482 rows=110 loops=1)
         ->  Hash Join  (cost=3.45..15835.05 rows=1 width=82) (actual 
time=913.093..18954.951 rows=110 loops=1)
               Hash Cond: ("outer".fkserviceinstancestatusid = 
"inner".serviceinstancestatusid)
               ->  Hash Join  (cost=2.38..15833.96 rows=2 width=74) 
(actual time=175.139..18952.830 rows=358 loops=1)
                     Hash Cond: ("outer".fkserviceofferingid = 
"inner".serviceofferingid)
                     ->  Seq Scan on serviceinstance si  
(cost=0.00..15831.52 rows=7 width=78) (actual time=174.430..18948.210 
rows=358 loops=1)
                           Filter: (((subplan) = 'FL'::text) AND 
((subplan) = '099'::text))
                           SubPlan
                             ->  Result  (cost=0.00..0.01 rows=1 
width=0) (actual time=0.090..0.093 rows=1 loops=3923)
                             ->  Result  (cost=0.00..0.01 rows=1 
width=0) (actual time=0.058..0.061 rows=1 loops=265617)
                     ->  Hash  (cost=2.38..2.38 rows=3 width=4) (actual 
time=0.444..0.444 rows=0 loops=1)
                           ->  Hash Join  (cost=1.08..2.38 rows=3 
width=4) (actual time=0.312..0.428 rows=1 loops=1)
                                 Hash Cond: ("outer".fkserviceid = 
"inner".serviceid)
                                 ->  Seq Scan on serviceoffering so  
(cost=0.00..1.18 rows=18 width=8) (actual time=0.005..0.068 rows=18 loops=1)
                                 ->  Hash  (cost=1.07..1.07 rows=1 
width=4) (actual time=0.036..0.036 rows=0 loops=1)
                                       ->  Seq Scan on service s  
(cost=0.00..1.07 rows=1 width=4) (actual time=0.014..0.019 rows=1 loops=1)
                                             Filter: (servicename = 
'alert'::text)
               ->  Hash  (cost=1.06..1.06 rows=1 width=16) (actual 
time=0.044..0.044 rows=0 loops=1)
                     ->  Seq Scan on serviceinstancestatus sis  
(cost=0.00..1.06 rows=1 width=16) (actual time=0.017..0.024 rows=1 loops=1)
                           Filter: (status = 'ACTIVE'::text)
         ->  Index Scan using pk_account_accountid on account a  
(cost=0.00..3.82 rows=1 width=8) (actual time=0.012..0.016 rows=1 loops=110)
               Index Cond: ("outer".fkaccountid = a.accountid)
   ->  Index Scan using pk_contact_contactid on contact c  
(cost=0.00..3.24 rows=1 width=47) (actual time=0.014..0.018 rows=1 
loops=110)
         Index Cond: ("outer".fkcontactid = c.contactid)
   SubPlan
     ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual 
time=0.072..0.075 rows=1 loops=110)
     ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual 
time=0.079..0.082 rows=1 loops=110)
     ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual 
time=0.086..0.089 rows=1 loops=110)
 Total runtime: 18992.694 ms
(30 rows)

Time: 18996.203 ms

--> As you can see the ->  Seq Scan on serviceinstance si  
(cost=0.00..15831.52 rows=7 width=78) (actual time=174.430..18948.210 
rows=358 loops=1) was taking too long .
    same query when i disable the seq-scan it uses index-scan and its 
much faster now

set enable_seqscan=false;
SET
Time: 0.508 ms
explain analyze
select * from provisioning.alerts where countystate = 'FL' and countyno 
= '099' and status = 'ACTIVE' ;

                                                                                             
QUERY PLAN                                      
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Nested Loop  (cost=9.10..16676.10 rows=1 width=125) (actual 
time=24.792..3898.939 rows=110 loops=1)
   ->  Nested Loop  (cost=9.10..16672.81 rows=1 width=86) (actual 
time=24.383..3862.025 rows=110 loops=1)
         ->  Hash Join  (cost=9.10..16668.97 rows=1 width=82) (actual 
time=24.351..3858.351 rows=110 loops=1)
               Hash Cond: ("outer".fkserviceofferingid = 
"inner".serviceofferingid)
               ->  Nested Loop  (cost=0.00..16659.85 rows=2 width=86) 
(actual time=8.449..3841.260 rows=110 loops=1)
                     ->  Index Scan using 
pk_serviceinstancestatus_serviceinstancestatusid on 
serviceinstancestatus sis  (cost=0.00..3.07 rows=1 width=16) (actual 
time=3.673..3.684 rows=1 loops=1)
                           Filter: (status = 'ACTIVE'::text)
                     ->  Index Scan using 
idx_serviceinstance_fkserviceinstancestatusid on serviceinstance si  
(cost=0.00..16656.76 rows=2 width=78) (actual time=4.755..3836.399 
rows=110 loops=1)
                           Index Cond: (si.fkserviceinstancestatusid = 
"outer".serviceinstancestatusid)
                           Filter: (((subplan) = 'FL'::text) AND 
((subplan) = '099'::text))
                           SubPlan
                             ->  Result  (cost=0.00..0.01 rows=1 
width=0) (actual time=0.125..0.128 rows=1 loops=1283)
                             ->  Result  (cost=0.00..0.01 rows=1 
width=0) (actual time=0.083..0.086 rows=1 loops=26146)
               ->  Hash  (cost=9.09..9.09 rows=3 width=4) (actual 
time=15.661..15.661 rows=0 loops=1)
                     ->  Nested Loop  (cost=0.00..9.09 rows=3 width=4) 
(actual time=15.617..15.637 rows=1 loops=1)
                           ->  Index Scan using uk_service_servicename 
on service s  (cost=0.00..3.96 rows=1 width=4) (actual 
time=11.231..11.236 rows=1 loops=1)
                                 Index Cond: (servicename = 'alert'::text)
                           ->  Index Scan using 
idx_serviceoffering_fkserviceid on serviceoffering so  (cost=0.00..5.09 
rows=3 width=8) (actual time=4.366..4.371 rows=1 loops=1)
                                 Index Cond: ("outer".serviceid = 
so.fkserviceid)
         ->  Index Scan using pk_account_accountid on account a  
(cost=0.00..3.82 rows=1 width=8) (actual time=0.013..0.017 rows=1 loops=110)
               Index Cond: ("outer".fkaccountid = a.accountid)
   ->  Index Scan using pk_contact_contactid on contact c  
(cost=0.00..3.24 rows=1 width=47) (actual time=0.013..0.017 rows=1 
loops=110)
         Index Cond: ("outer".fkcontactid = c.contactid)
   SubPlan
     ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual 
time=0.081..0.084 rows=1 loops=110)
     ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual 
time=0.088..0.091 rows=1 loops=110)
     ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual 
time=0.098..0.101 rows=1 loops=110)
 Total runtime: 3899.589 ms
(28 rows)


Here is the view definition
-------------------------------

       View "provisioning.alerts"
      Column       |  Type   | Modifiers
-------------------+---------+-----------
 serviceinstanceid | integer |
 accountid         | integer |
 firstname         | text    |
 lastname          | text    |
 email             | text    |
 status            | text    |
 affiliate         | text    |
 affiliatesub      | text    |
 domain            | text    |
 countyno          | text    |
 countystate       | text    |
 listingtype       | text    |
View definition:
 SELECT si.serviceinstanceid, a.accountid, c.firstname, c.lastname, 
c.email, sis.status, si.affiliate, si.affiliatesub, si."domain",
               ( SELECT get_parametervalue(si.serviceinstanceid, 
'countyNo'::text) AS get_parametervalue) AS countyno,
              ( SELECT get_parametervalue(si.serviceinstanceid, 
'countyState'::text) AS get_parametervalue) AS countystate,
              ( SELECT get_parametervalue(si.serviceinstanceid, 
'listingType'::text) AS get_parametervalue) AS listingtype
   FROM provisioning.account a, common.contact c, provisioning.service 
s, provisioning.serviceoffering so, provisioning.serviceinstance si, 
provisioning.serviceinstancestatus sis
  WHERE si.fkserviceofferingid = so.serviceofferingid
  AND si.fkserviceinstancestatusid = sis.serviceinstancestatusid
 AND s.serviceid = so.fkserviceid
 AND a.fkcontactid = c.contactid
 AND si.fkaccountid = a.accountid
AND s.servicename = 'alert'::text;

Function Definition
----------------------

CREATE OR REPLACE FUNCTION get_parametervalue(v_fkserviceinstanceid 
integer, v_name text) RETURNS TEXT AS $$
DECLARE
        v_value        text;
BEGIN
        SELECT  p.value
        INTO    v_value
        FROM    provisioning.serviceinstanceparameter sip, 
common.parameter p
        WHERE   fkserviceinstanceid = v_fkserviceinstanceid
        AND     sip.fkparameterid = p.parameterid
        AND     p.name = v_name;

        RETURN  v_value;

END

Serviceinstance table stats
-----------------------------

select relname, relpages, reltuples from pg_class where relname = 
'serviceinstance';
     relname     | relpages | reltuples
-----------------+----------+-----------
 serviceinstance |     5207 |    265613

$$ language plpgsql







^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* Postgres8.0 planner chooses WRONG plan
@ 2006-01-11 15:27 Pallav Kalva <pkalva@livedatagroup.com>
  2006-01-11 16:07 ` Re: Postgres8.0 planner chooses WRONG plan Tom Lane <tgl@sss.pgh.pa.us>
  0 siblings, 1 reply; 5+ messages in thread

From: Pallav Kalva @ 2006-01-11 15:27 UTC (permalink / raw)
  To: pgsql-performance

Hi ,


   I am having problem optimizing this query, Postgres optimizer uses a 
plan which invloves seq-scan on a table. And when I choose a option to 
disable seq-scan it uses index-scan and obviously the query is much faster.
   All tables are daily vacummed and analyzed as per docs.

  Why cant postgres use index-scan ?


Postgres Version:8.0.2
Platform : Fedora

Here is the explain analyze output. Let me know if any more information 
is needed.  Can we make postgres use index scan for this query ?

Thanks!
Pallav.

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 

explain analyze
select * from provisioning.alerts where countystate = 'FL' and countyno 
= '099' and status = 'ACTIVE' ;

                                                                   QUERY 
PLAN                                                               
-------------------------------------------------------------------------------------------------------------------------------------------------- 

Nested Loop  (cost=3.45..15842.17 rows=1 width=125) (actual 
time=913.491..18992.009 rows=110 loops=1)
  ->  Nested Loop  (cost=3.45..15838.88 rows=1 width=86) (actual 
time=913.127..18958.482 rows=110 loops=1)
        ->  Hash Join  (cost=3.45..15835.05 rows=1 width=82) (actual 
time=913.093..18954.951 rows=110 loops=1)
              Hash Cond: ("outer".fkserviceinstancestatusid = 
"inner".serviceinstancestatusid)
              ->  Hash Join  (cost=2.38..15833.96 rows=2 width=74) 
(actual time=175.139..18952.830 rows=358 loops=1)
                    Hash Cond: ("outer".fkserviceofferingid = 
"inner".serviceofferingid)
                    ->  Seq Scan on serviceinstance si  
(cost=0.00..15831.52 rows=7 width=78) (actual time=174.430..18948.210 
rows=358 loops=1)
                          Filter: (((subplan) = 'FL'::text) AND 
((subplan) = '099'::text))
                          SubPlan
                            ->  Result  (cost=0.00..0.01 rows=1 width=0) 
(actual time=0.090..0.093 rows=1 loops=3923)
                            ->  Result  (cost=0.00..0.01 rows=1 width=0) 
(actual time=0.058..0.061 rows=1 loops=265617)
                    ->  Hash  (cost=2.38..2.38 rows=3 width=4) (actual 
time=0.444..0.444 rows=0 loops=1)
                          ->  Hash Join  (cost=1.08..2.38 rows=3 
width=4) (actual time=0.312..0.428 rows=1 loops=1)
                                Hash Cond: ("outer".fkserviceid = 
"inner".serviceid)
                                ->  Seq Scan on serviceoffering so  
(cost=0.00..1.18 rows=18 width=8) (actual time=0.005..0.068 rows=18 
loops=1)
                                ->  Hash  (cost=1.07..1.07 rows=1 
width=4) (actual time=0.036..0.036 rows=0 loops=1)
                                      ->  Seq Scan on service s  
(cost=0.00..1.07 rows=1 width=4) (actual time=0.014..0.019 rows=1 loops=1)
                                            Filter: (servicename = 
'alert'::text)
              ->  Hash  (cost=1.06..1.06 rows=1 width=16) (actual 
time=0.044..0.044 rows=0 loops=1)
                    ->  Seq Scan on serviceinstancestatus sis  
(cost=0.00..1.06 rows=1 width=16) (actual time=0.017..0.024 rows=1 loops=1)
                          Filter: (status = 'ACTIVE'::text)
        ->  Index Scan using pk_account_accountid on account a  
(cost=0.00..3.82 rows=1 width=8) (actual time=0.012..0.016 rows=1 
loops=110)
              Index Cond: ("outer".fkaccountid = a.accountid)
  ->  Index Scan using pk_contact_contactid on contact c  
(cost=0.00..3.24 rows=1 width=47) (actual time=0.014..0.018 rows=1 
loops=110)
        Index Cond: ("outer".fkcontactid = c.contactid)
  SubPlan
    ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual 
time=0.072..0.075 rows=1 loops=110)
    ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual 
time=0.079..0.082 rows=1 loops=110)
    ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual 
time=0.086..0.089 rows=1 loops=110)
Total runtime: 18992.694 ms
(30 rows)

Time: 18996.203 ms

--> As you can see the ->  Seq Scan on serviceinstance si  
(cost=0.00..15831.52 rows=7 width=78) (actual time=174.430..18948.210 
rows=358 loops=1) was taking too long .
   same query when i disable the seq-scan it uses index-scan and its 
much faster now

set enable_seqscan=false;
SET
Time: 0.508 ms
explain analyze
select * from provisioning.alerts where countystate = 'FL' and countyno 
= '099' and status = 'ACTIVE' ;

                                                                                            
QUERY PLAN                                      
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 

Nested Loop  (cost=9.10..16676.10 rows=1 width=125) (actual 
time=24.792..3898.939 rows=110 loops=1)
  ->  Nested Loop  (cost=9.10..16672.81 rows=1 width=86) (actual 
time=24.383..3862.025 rows=110 loops=1)
        ->  Hash Join  (cost=9.10..16668.97 rows=1 width=82) (actual 
time=24.351..3858.351 rows=110 loops=1)
              Hash Cond: ("outer".fkserviceofferingid = 
"inner".serviceofferingid)
              ->  Nested Loop  (cost=0.00..16659.85 rows=2 width=86) 
(actual time=8.449..3841.260 rows=110 loops=1)
                    ->  Index Scan using 
pk_serviceinstancestatus_serviceinstancestatusid on 
serviceinstancestatus sis  (cost=0.00..3.07 rows=1 width=16) (actual 
time=3.673..3.684 rows=1 loops=1)
                          Filter: (status = 'ACTIVE'::text)
                    ->  Index Scan using 
idx_serviceinstance_fkserviceinstancestatusid on serviceinstance si  
(cost=0.00..16656.76 rows=2 width=78) (actual time=4.755..3836.399 
rows=110 loops=1)
                          Index Cond: (si.fkserviceinstancestatusid = 
"outer".serviceinstancestatusid)
                          Filter: (((subplan) = 'FL'::text) AND 
((subplan) = '099'::text))
                          SubPlan
                            ->  Result  (cost=0.00..0.01 rows=1 width=0) 
(actual time=0.125..0.128 rows=1 loops=1283)
                            ->  Result  (cost=0.00..0.01 rows=1 width=0) 
(actual time=0.083..0.086 rows=1 loops=26146)
              ->  Hash  (cost=9.09..9.09 rows=3 width=4) (actual 
time=15.661..15.661 rows=0 loops=1)
                    ->  Nested Loop  (cost=0.00..9.09 rows=3 width=4) 
(actual time=15.617..15.637 rows=1 loops=1)
                          ->  Index Scan using uk_service_servicename on 
service s  (cost=0.00..3.96 rows=1 width=4) (actual time=11.231..11.236 
rows=1 loops=1)
                                Index Cond: (servicename = 'alert'::text)
                          ->  Index Scan using 
idx_serviceoffering_fkserviceid on serviceoffering so  (cost=0.00..5.09 
rows=3 width=8) (actual time=4.366..4.371 rows=1 loops=1)
                                Index Cond: ("outer".serviceid = 
so.fkserviceid)
        ->  Index Scan using pk_account_accountid on account a  
(cost=0.00..3.82 rows=1 width=8) (actual time=0.013..0.017 rows=1 
loops=110)
              Index Cond: ("outer".fkaccountid = a.accountid)
  ->  Index Scan using pk_contact_contactid on contact c  
(cost=0.00..3.24 rows=1 width=47) (actual time=0.013..0.017 rows=1 
loops=110)
        Index Cond: ("outer".fkcontactid = c.contactid)
  SubPlan
    ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual 
time=0.081..0.084 rows=1 loops=110)
    ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual 
time=0.088..0.091 rows=1 loops=110)
    ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual 
time=0.098..0.101 rows=1 loops=110)
Total runtime: 3899.589 ms
(28 rows)


Here is the view definition
-------------------------------

      View "provisioning.alerts"
     Column       |  Type   | Modifiers
-------------------+---------+-----------
serviceinstanceid | integer |
accountid         | integer |
firstname         | text    |
lastname          | text    |
email             | text    |
status            | text    |
affiliate         | text    |
affiliatesub      | text    |
domain            | text    |
countyno          | text    |
countystate       | text    |
listingtype       | text    |
View definition:
SELECT si.serviceinstanceid, a.accountid, c.firstname, c.lastname, 
c.email, sis.status, si.affiliate, si.affiliatesub, si."domain",
              ( SELECT get_parametervalue(si.serviceinstanceid, 
'countyNo'::text) AS get_parametervalue) AS countyno,
             ( SELECT get_parametervalue(si.serviceinstanceid, 
'countyState'::text) AS get_parametervalue) AS countystate,
             ( SELECT get_parametervalue(si.serviceinstanceid, 
'listingType'::text) AS get_parametervalue) AS listingtype
  FROM provisioning.account a, common.contact c, provisioning.service s, 
provisioning.serviceoffering so, provisioning.serviceinstance si, 
provisioning.serviceinstancestatus sis
 WHERE si.fkserviceofferingid = so.serviceofferingid
 AND si.fkserviceinstancestatusid = sis.serviceinstancestatusid
AND s.serviceid = so.fkserviceid
AND a.fkcontactid = c.contactid
AND si.fkaccountid = a.accountid
AND s.servicename = 'alert'::text;

Function Definition
----------------------

CREATE OR REPLACE FUNCTION get_parametervalue(v_fkserviceinstanceid 
integer, v_name text) RETURNS TEXT AS $$
DECLARE
       v_value        text;
BEGIN
       SELECT  p.value
       INTO    v_value
       FROM    provisioning.serviceinstanceparameter sip, 
common.parameter p
       WHERE   fkserviceinstanceid = v_fkserviceinstanceid
       AND     sip.fkparameterid = p.parameterid
       AND     p.name = v_name;

       RETURN  v_value;

END

Serviceinstance table stats
-----------------------------

select relname, relpages, reltuples from pg_class where relname = 
'serviceinstance';
    relname     | relpages | reltuples
-----------------+----------+-----------
serviceinstance |     5207 |    265613

$$ language plpgsql







^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* Re: Postgres8.0 planner chooses WRONG plan
  2006-01-11 15:27 Postgres8.0 planner chooses WRONG plan Pallav Kalva <pkalva@livedatagroup.com>
@ 2006-01-11 16:07 ` Tom Lane <tgl@sss.pgh.pa.us>
  2006-01-11 16:44   ` Re: Postgres8.0 planner chooses WRONG plan Pallav Kalva <pkalva@livedatagroup.com>
  0 siblings, 1 reply; 5+ messages in thread

From: Tom Lane @ 2006-01-11 16:07 UTC (permalink / raw)
  To: Pallav Kalva <pkalva@livedatagroup.com>; +Cc: pgsql-performance

Pallav Kalva <pkalva@livedatagroup.com> writes:
>    I am having problem optimizing this query,

Get rid of the un-optimizable function inside the view.  You've
converted something that should be a join into an unreasonably large
number of function calls.

>                     ->  Seq Scan on serviceinstance si  
> (cost=0.00..15831.52 rows=7 width=78) (actual time=174.430..18948.210 
> rows=358 loops=1)
>                           Filter: (((subplan) = 'FL'::text) AND 
> ((subplan) = '099'::text))
>                           SubPlan
>                             ->  Result  (cost=0.00..0.01 rows=1 width=0) 
> (actual time=0.090..0.093 rows=1 loops=3923)
>                             ->  Result  (cost=0.00..0.01 rows=1 width=0) 
> (actual time=0.058..0.061 rows=1 loops=265617)

The bulk of the cost here is in the second subplan (0.061 * 265617 =
16202.637 msec total runtime), and there's not a darn thing Postgres
can do to improve this because the work is all down inside a "black box"
function.  In fact the planner does not even know that the function call
is expensive, else it would have preferred a plan that requires fewer
evaluations of the function.  The alternative plan you show is *not*
faster "because it's an indexscan"; it's faster because get_parametervalue
is evaluated fewer times.

The useless sub-SELECTs atop the function calls are adding their own
little increment of wasted time, too.  I'm not sure how bad that is
relative to the function calls, but it's certainly not helping.

			regards, tom lane



^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* Re: Postgres8.0 planner chooses WRONG plan
  2006-01-11 15:27 Postgres8.0 planner chooses WRONG plan Pallav Kalva <pkalva@livedatagroup.com>
  2006-01-11 16:07 ` Re: Postgres8.0 planner chooses WRONG plan Tom Lane <tgl@sss.pgh.pa.us>
@ 2006-01-11 16:44   ` Pallav Kalva <pkalva@livedatagroup.com>
  2006-01-11 19:02     ` Re: Postgres8.0 planner chooses WRONG plan Jim C. Nasby <jnasby@pervasive.com>
  0 siblings, 1 reply; 5+ messages in thread

From: Pallav Kalva @ 2006-01-11 16:44 UTC (permalink / raw)
  To: Tom Lane <tgl@sss.pgh.pa.us>; +Cc: pgsql-performance

Hi Tom,

     Thanks! for your input, the view was written first without using 
the function but its an ugly big with all the joins and its much slower 
that way. Below is the view without the function and its explain analzye 
output , as you can see the it takes almost 2 min to run this query with 
this view . Is there any way to optimize or make changes to this view ?

Thanks!
Pallav.


View Definition
-------------------

create or replace view provisioning.alertserviceinstanceold as
SELECT services.serviceinstanceid, a.accountid, c.firstname, c.lastname, 
c.email, services.countyno, services.countystate, services.listingtype 
AS listingtypename, services.status, services.affiliate, 
services.affiliatesub, services."domain"
   FROM provisioning.account a
   JOIN common.contact c ON a.fkcontactid = c.contactid
   JOIN ( SELECT p1.serviceinstanceid, p1.accountid, p1.countyno, 
p2.countystate, p3.listingtype, p1.status, p1.affiliate, 
p1.affiliatesub, p1."domain"
      FROM ( SELECT si.serviceinstanceid, si.affiliate, si.affiliatesub, 
si."domain", si.fkaccountid AS accountid, p.value AS countyno, sis.status
              FROM provisioning.service s
         JOIN provisioning.serviceoffering so ON s.serviceid = 
so.fkserviceid
    JOIN provisioning.serviceinstance si ON so.serviceofferingid = 
si.fkserviceofferingid
   JOIN provisioning.serviceinstancestatus sis ON 
si.fkserviceinstancestatusid = sis.serviceinstancestatusid
   JOIN provisioning.serviceinstanceparameter sip ON 
si.serviceinstanceid = sip.fkserviceinstanceid
   JOIN common.parameter p ON sip.fkparameterid = p.parameterid
  WHERE s.servicename = 'alert'::text AND p.name = 'countyNo'::text) p1
   JOIN ( SELECT si.serviceinstanceid, si.affiliate, si.affiliatesub, 
si."domain", si.fkaccountid AS accountid, p.value AS countystate, sis.status
              FROM provisioning.service s
         JOIN provisioning.serviceoffering so ON s.serviceid = 
so.fkserviceid
    JOIN provisioning.serviceinstance si ON so.serviceofferingid = 
si.fkserviceofferingid
   JOIN provisioning.serviceinstancestatus sis ON 
si.fkserviceinstancestatusid = sis.serviceinstancestatusid
   JOIN provisioning.serviceinstanceparameter sip ON 
si.serviceinstanceid = sip.fkserviceinstanceid
   JOIN common.parameter p ON sip.fkparameterid = p.parameterid
  WHERE s.servicename = 'alert'::text AND p.name = 'countyState'::text) 
p2 ON p1.accountid = p2.accountid AND p1.serviceinstanceid = 
p2.serviceinstanceid
   JOIN ( SELECT si.serviceinstanceid, si.affiliate, si.affiliatesub, 
si."domain", si.fkaccountid AS accountid, p.value AS listingtype, sis.status
         FROM provisioning.service s
    JOIN provisioning.serviceoffering so ON s.serviceid = so.fkserviceid
   JOIN provisioning.serviceinstance si ON so.serviceofferingid = 
si.fkserviceofferingid
   JOIN provisioning.serviceinstancestatus sis ON 
si.fkserviceinstancestatusid = sis.serviceinstancestatusid
   JOIN provisioning.serviceinstanceparameter sip ON 
si.serviceinstanceid = sip.fkserviceinstanceid
   JOIN common.parameter p ON sip.fkparameterid = p.parameterid
  WHERE s.servicename = 'alert'::text AND p.name = 'listingType'::text) 
p3 ON p2.accountid = p3.accountid AND p2.serviceinstanceid = 
p3.serviceinstanceid) services
ON a.accountid = services.accountid
ORDER BY services.serviceinstanceid;

Explain Analyze
------------------
explain analyze
select * from provisioning.alertserviceinstanceold where countystate = 
'FL' and countyno = '099' and status = 'ACTIVE' ;

                                                                                                                            
QUERY PLAN

----------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------
 Subquery Scan alertserviceinstanceold  (cost=31954.24..31954.25 rows=1 
width=328) (actual time=113485.801..113487.024 rows=110 loops=1)
   ->  Sort  (cost=31954.24..31954.24 rows=1 width=152) (actual 
time=113485.787..113486.123 rows=110 loops=1)
         Sort Key: si.serviceinstanceid
         ->  Hash Join  (cost=20636.38..31954.23 rows=1 width=152) 
(actual time=109721.688..113485.311 rows=110 loops=1)
               Hash Cond: ("outer".accountid = "inner".fkaccountid)
               ->  Hash Join  (cost=6595.89..16770.25 rows=228696 
width=47) (actual time=1742.592..4828.396 rows=229855 loops=1)
                     Hash Cond: ("outer".contactid = "inner".fkcontactid)
                     ->  Seq Scan on contact c  (cost=0.00..4456.96 
rows=228696 width=47) (actual time=0.006..1106.459 rows=229868 loops=1)
                     ->  Hash  (cost=6024.11..6024.11 rows=228711 
width=8) (actual time=1742.373..1742.373 rows=0 loops=1)
                           ->  Seq Scan on account a  
(cost=0.00..6024.11 rows=228711 width=8) (actual time=0.010..990.597 
rows=229855 loops=1)
               ->  Hash  (cost=14040.49..14040.49 rows=1 width=117) 
(actual time=107911.397..107911.397 rows=0 loops=1)
                     ->  Nested Loop  (cost=10.34..14040.49 rows=1 
width=117) (actual time=1185.383..107910.738 rows=110 loops=1)
                           ->  Nested Loop  (cost=10.34..14037.45 rows=1 
width=112) (actual time=1185.278..107898.885 rows=550 loops=1)
                                 ->  Hash Join  (cost=10.34..14033.98 
rows=1 width=124) (actual time=1185.224..107888.542 rows=110 loops=1)
                                       Hash Cond: 
("outer".fkserviceofferingid = "inner".serviceofferingid)
                                       ->  Hash Join  
(cost=7.96..14031.58 rows=1 width=128) (actual time=1184.490..107886.329 
rows=110 loops=1)
                                             Hash Cond: 
("outer".fkserviceinstancestatusid = "inner".serviceinstancestatusid)
                                             ->  Nested Loop  
(cost=6.90..14030.50 rows=1 width=132) (actual time=1184.151..107884.302 
rows=110 loops=1)
                                                   Join Filter: 
("outer".fkaccountid = "inner".fkaccountid)
                                                   ->  Nested Loop  
(cost=6.90..14025.09 rows=1 width=116) (actual time=1184.123..107880.635 
rows=110 loops=1)
                                                         Join Filter: 
(("outer".fkaccountid = "inner".fkaccountid) AND 
("outer".serviceinstanceid = "inner".serviceinstanceid))
                                                         ->  Hash Join  
(cost=3.45..636.39 rows=1 width=95) (actual time=85.524..293.387 
rows=226 loops=1)
                                                               Hash 
Cond: ("outer".fkserviceinstancestatusid = "inner".serviceinstancestatusid)
                                                               ->  Hash 
Join  (cost=2.38..635.29 rows=4 width=87) (actual time=6.894..289.000 
rows=663 loops=1)
                                                                     
Hash Cond: ("outer".fkserviceofferingid = "inner".serviceofferingid)
                                                                     ->  
Nested Loop  (cost=0.00..632.75 rows=23 width=91) (actual 
time=6.176..281.620 rows=663 loops=1)
                                                                           
->  Nested Loop  (cost=0.00..508.26 rows=23 width=13) (actual 
time=6.138..221.590 rows=663 loops=1)
                                                                                 
->  Index Scan using idx_parameter_value on parameter p  
(cost=0.00..437.42 rows=23 width=13) (actual time=6.091..20.656 rows=663 
loops=1)
                                                                                       
Index Cond: (value = '099'::text)
                                                                                       
Filter: (name = 'countyNo'::text)
                                                                                 
->  Index Scan using idx_serviceinstanceparameter_fkparameterid on 
serviceinstanceparameter sip  (cost=0.00..3.07 rows=1 width=8) (actual 
time=0.278..0.288 rows=1 loops=663)
                                                                                       
Index Cond: (sip.fkparameterid = "outer".parameterid)
                                                                           
->  Index Scan using pk_serviceinstance_serviceinstanceid on 
serviceinstance si  (cost=0.00..5.40 rows=1 width=78) (actual 
time=0.041..0.073 rows=1 loops=663)
                                                                                 
Index Cond: (si.serviceinstanceid = "outer".fkserviceinstanceid)
                                                                     ->  
Hash  (cost=2.38..2.38 rows=3 width=4) (actual time=0.445..0.445 rows=0 
loops=1)
                                                                           
->  Hash Join  (cost=1.08..2.38 rows=3 width=4) (actual 
time=0.314..0.426 rows=1 loops=1)
                                                                                 
Hash Cond: ("outer".fkserviceid = "inner".serviceid)
                                                                                 
->  Seq Scan on serviceoffering so  (cost=0.00..1.18 rows=18width=8) 
(actual time=0.005..0.065 rows=18 loops=1)
                                                                                 
->  Hash  (cost=1.07..1.07 rows=1 width=4) (actual time=0.033..0.033 
rows=0 loops=1)
                                                                                       
->  Seq Scan on service s  (cost=0.00..1.07 rows=1 width=4) (actual 
time=0.011..0.016 rows=1 loops=1)
                                                                                             
Filter: (servicename = 'alert'::text)
                                                               ->  Hash  
(cost=1.06..1.06 rows=1 width=16) (actual time=0.031..0.031 rows=0 loops=1)
                                                                     ->  
Seq Scan on serviceinstancestatus sis  (cost=0.00..1.06 rows=1 width=16) 
(actual time=0.008..0.014 rows=1 loops=1)
                                                                           
Filter: (status = 'ACTIVE'::text)
                                                         ->  Hash Join  
(cost=3.45..13386.23 rows=165 width=21) (actual time=0.119..461.891 
rows=3935 loops=226)
                                                               Hash 
Cond: ("outer".fkserviceinstancestatusid = "inner".serviceinstancestatusid)
                                                               ->  Hash 
Join  (cost=2.38..13382.69 rows=165 width=25) (actual 
time=0.110..432.555 rows=3935 loops=226)
                                                                     
Hash Cond: ("outer".fkserviceofferingid = "inner".serviceofferingid)
                                                                     ->  
Nested Loop  (cost=0.00..13373.71 rows=990 width=29) (actual 
time=0.098..400.805 rows=3935 loops=226)
                                                                           
->  Nested Loop  (cost=0.00..8015.16 rows=990 width=13) (actual 
time=0.035..267.634 rows=3935 loops=226)
                                                                                 
->  Seq Scan on parameter p  (cost=0.00..4968.81 rows=989 width=13) 
(actual time=0.008..131.735 rows=3935 loops=226)
                                                                                       
Filter: ((name = 'countyState'::text) AND (value = 'FL'::text))
                                                                                 
->  Index Scan using idx_serviceinstanceparameter_fkparameterid on 
serviceinstanceparameter sip  (cost=0.00..3.07 rows=1 width=8) (actual 
time=0.015..0.020 rows=1 loops=889310)
                                                                                       
Index Cond: (sip.fkparameterid = "outer".parameterid)
                                                                           
->  Index Scan using pk_serviceinstance_serviceinstanceid on 
serviceinstance si  (cost=0.00..5.40 rows=1 width=16) (actual 
time=0.012..0.019 rows=1 loops=889310)
                                                                                 
Index Cond: (si.serviceinstanceid = "outer".fkserviceinstanceid)
                                                                     ->  
Hash  (cost=2.38..2.38 rows=3 width=4) (actual time=0.439..0.439 rows=0 
loops=1)
                                                                           
->  Hash Join  (cost=1.08..2.38 rows=3 width=4) (actual 
time=0.310..0.423 rows=1 loops=1)
                                                                                 
Hash Cond: ("outer".fkserviceid = "inner".serviceid)
                                                                                 
->  Seq Scan on serviceoffering so  (cost=0.00..1.18 rows=18 width=8) 
(actual time=0.006..0.065 rows=18 loops=1)
                                                                                 
->  Hash  (cost=1.07..1.07 rows=1 width=4) (actual time=0.035..0.035 
rows=0 loops=1)
                                                                                       
->  Seq Scan on service s  (cost=0.00..1.07 rows=1 width=4) (actual 
time=0.013..0.018 rows=1 loops=1)
                                                                                             
Filter: (servicename = 'alert'::text)
                                                               ->  Hash  
(cost=1.05..1.05 rows=5 width=4) (actual time=0.059..0.059 rows=0 loops=1)
                                                                     ->  
Seq Scan on serviceinstancestatus sis  (cost=0.00..1.05 rows=5 width=4) 
(actual time=0.010..0.029 rows=5 loops=1)
                                                   ->  Index Scan using 
pk_serviceinstance_serviceinstanceid on serviceinstance si  
(cost=0.00..5.40 rows=1 width=16) (actual time=0.009..0.012 rows=1 
loops=110)
                                                         Index Cond: 
(si.serviceinstanceid = "outer".fkserviceinstanceid)
                                             ->  Hash  (cost=1.05..1.05 
rows=5 width=4) (actual time=0.055..0.055 rows=0 loops=1)
                                                   ->  Seq Scan on 
serviceinstancestatus sis  (cost=0.00..1.05 rows=5 width=4) (actual 
time=0.008..0.025 rows=5 loops=1)
                                       ->  Hash  (cost=2.38..2.38 rows=3 
width=4) (actual time=0.461..0.461 rows=0 loops=1)
                                             ->  Hash Join  
(cost=1.08..2.38 rows=3 width=4) (actual time=0.325..0.445 rows=1 loops=1)
                                                   Hash Cond: 
("outer".fkserviceid = "inner".serviceid)
                                                   ->  Seq Scan on 
serviceoffering so  (cost=0.00..1.18 rows=18 width=8) (actual 
time=0.006..0.074 rows=18 loops=1)
                                                   ->  Hash  
(cost=1.07..1.07 rows=1 width=4) (actual time=0.044..0.044 rows=0 loops=1)
                                                         ->  Seq Scan on 
service s  (cost=0.00..1.07 rows=1 width=4) (actual time=0.022..0.027 
rows=1 loops=1)
                                                               Filter: 
(servicename = 'alert'::text)
                                 ->  Index Scan using 
idx_serviceinstanceparameter_fkserviceinstanceid on 
serviceinstanceparameter sip  (cost=0.00..3.41 rows=5 width=8) (actual 
time=0.018..0.038 rows=5 loops=110)
                                       Index Cond: 
(sip.fkserviceinstanceid = "outer".fkserviceinstanceid)
                           ->  Index Scan using pk_parameter_parameterid 
on parameter p  (cost=0.00..3.02 rows=1 width=13) (actual 
time=0.011..0.012 rows=0 loops=550)
                                 Index Cond: ("outer".fkparameterid = 
p.parameterid)
                                 Filter: (name = 'listingType'::text)

 Total runtime: 113490.582 ms
(82 rows)



Tom Lane wrote:
>Pallav Kalva <pkalva@livedatagroup.com> writes:
>  
>>   I am having problem optimizing this query,
>>    
>
>Get rid of the un-optimizable function inside the view.  You've
>converted something that should be a join into an unreasonably large
>number of function calls.
>
>  
>>                    ->  Seq Scan on serviceinstance si  
>>(cost=0.00..15831.52 rows=7 width=78) (actual time=174.430..18948.210 
>>rows=358 loops=1)
>>                          Filter: (((subplan) = 'FL'::text) AND 
>>((subplan) = '099'::text))
>>                          SubPlan
>>                            ->  Result  (cost=0.00..0.01 rows=1 width=0) 
>>(actual time=0.090..0.093 rows=1 loops=3923)
>>                            ->  Result  (cost=0.00..0.01 rows=1 width=0) 
>>(actual time=0.058..0.061 rows=1 loops=265617)
>>    
>
>The bulk of the cost here is in the second subplan (0.061 * 265617 =
>16202.637 msec total runtime), and there's not a darn thing Postgres
>can do to improve this because the work is all down inside a "black box"
>function.  In fact the planner does not even know that the function call
>is expensive, else it would have preferred a plan that requires fewer
>evaluations of the function.  The alternative plan you show is *not*
>faster "because it's an indexscan"; it's faster because get_parametervalue
>is evaluated fewer times.
>
>The useless sub-SELECTs atop the function calls are adding their own
>little increment of wasted time, too.  I'm not sure how bad that is
>relative to the function calls, but it's certainly not helping.
>
>			regards, tom lane
>
>  




^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* Re: Postgres8.0 planner chooses WRONG plan
  2006-01-11 15:27 Postgres8.0 planner chooses WRONG plan Pallav Kalva <pkalva@livedatagroup.com>
  2006-01-11 16:07 ` Re: Postgres8.0 planner chooses WRONG plan Tom Lane <tgl@sss.pgh.pa.us>
  2006-01-11 16:44   ` Re: Postgres8.0 planner chooses WRONG plan Pallav Kalva <pkalva@livedatagroup.com>
@ 2006-01-11 19:02     ` Jim C. Nasby <jnasby@pervasive.com>
  0 siblings, 0 replies; 5+ messages in thread

From: Jim C. Nasby @ 2006-01-11 19:02 UTC (permalink / raw)
  To: Pallav Kalva <pkalva@livedatagroup.com>; +Cc: Tom Lane <tgl@sss.pgh.pa.us>; pgsql-performance

On Wed, Jan 11, 2006 at 11:44:58AM -0500, Pallav Kalva wrote:
Some view you've got there... you might want to break that apart into
multiple views that are a bit easier to manage.
service_instance_with_status is a likely candidate, for example.

> View Definition
> -------------------
> 
> create or replace view provisioning.alertserviceinstanceold as
> SELECT services.serviceinstanceid, a.accountid, c.firstname, c.lastname, 
> c.email, services.countyno, services.countystate, services.listingtype 
> AS listingtypename, services.status, services.affiliate, 
> services.affiliatesub, services."domain"
>   FROM provisioning.account a
>   JOIN common.contact c ON a.fkcontactid = c.contactid
>   JOIN ( SELECT p1.serviceinstanceid, p1.accountid, p1.countyno, 
> p2.countystate, p3.listingtype, p1.status, p1.affiliate, 
> p1.affiliatesub, p1."domain"
>      FROM ( SELECT si.serviceinstanceid, si.affiliate, si.affiliatesub, 
> si."domain", si.fkaccountid AS accountid, p.value AS countyno, sis.status
>              FROM provisioning.service s
>         JOIN provisioning.serviceoffering so ON s.serviceid = 
> so.fkserviceid
>    JOIN provisioning.serviceinstance si ON so.serviceofferingid = 
> si.fkserviceofferingid
>   JOIN provisioning.serviceinstancestatus sis ON 
> si.fkserviceinstancestatusid = sis.serviceinstancestatusid
>   JOIN provisioning.serviceinstanceparameter sip ON 
> si.serviceinstanceid = sip.fkserviceinstanceid
>   JOIN common.parameter p ON sip.fkparameterid = p.parameterid
>  WHERE s.servicename = 'alert'::text AND p.name = 'countyNo'::text) p1
>   JOIN ( SELECT si.serviceinstanceid, si.affiliate, si.affiliatesub, 
> si."domain", si.fkaccountid AS accountid, p.value AS countystate, sis.status
>              FROM provisioning.service s
>         JOIN provisioning.serviceoffering so ON s.serviceid = 
> so.fkserviceid
>    JOIN provisioning.serviceinstance si ON so.serviceofferingid = 
> si.fkserviceofferingid
>   JOIN provisioning.serviceinstancestatus sis ON 
> si.fkserviceinstancestatusid = sis.serviceinstancestatusid
>   JOIN provisioning.serviceinstanceparameter sip ON 
> si.serviceinstanceid = sip.fkserviceinstanceid
>   JOIN common.parameter p ON sip.fkparameterid = p.parameterid
>  WHERE s.servicename = 'alert'::text AND p.name = 'countyState'::text) 
> p2 ON p1.accountid = p2.accountid AND p1.serviceinstanceid = 
> p2.serviceinstanceid
>   JOIN ( SELECT si.serviceinstanceid, si.affiliate, si.affiliatesub, 
> si."domain", si.fkaccountid AS accountid, p.value AS listingtype, sis.status
>         FROM provisioning.service s
>    JOIN provisioning.serviceoffering so ON s.serviceid = so.fkserviceid
>   JOIN provisioning.serviceinstance si ON so.serviceofferingid = 
> si.fkserviceofferingid
>   JOIN provisioning.serviceinstancestatus sis ON 
> si.fkserviceinstancestatusid = sis.serviceinstancestatusid
>   JOIN provisioning.serviceinstanceparameter sip ON 
> si.serviceinstanceid = sip.fkserviceinstanceid
>   JOIN common.parameter p ON sip.fkparameterid = p.parameterid
>  WHERE s.servicename = 'alert'::text AND p.name = 'listingType'::text) 
> p3 ON p2.accountid = p3.accountid AND p2.serviceinstanceid = 
> p3.serviceinstanceid) services
> ON a.accountid = services.accountid
> ORDER BY services.serviceinstanceid;
> 
> Explain Analyze
> ------------------
> explain analyze
> select * from provisioning.alertserviceinstanceold where countystate = 
> 'FL' and countyno = '099' and status = 'ACTIVE' ;
> 
>                                                                                                                            
> QUERY PLAN
> 
> ----------------------------------------------------------------------------------------------------------------------------------------------
> --------------------------------------------------------------------------------------------------------------------
> Subquery Scan alertserviceinstanceold  (cost=31954.24..31954.25 rows=1 
> width=328) (actual time=113485.801..113487.024 rows=110 loops=1)
>   ->  Sort  (cost=31954.24..31954.24 rows=1 width=152) (actual 
> time=113485.787..113486.123 rows=110 loops=1)
>         Sort Key: si.serviceinstanceid
>         ->  Hash Join  (cost=20636.38..31954.23 rows=1 width=152) 
> (actual time=109721.688..113485.311 rows=110 loops=1)
>               Hash Cond: ("outer".accountid = "inner".fkaccountid)
>               ->  Hash Join  (cost=6595.89..16770.25 rows=228696 
> width=47) (actual time=1742.592..4828.396 rows=229855 loops=1)
>                     Hash Cond: ("outer".contactid = "inner".fkcontactid)
>                     ->  Seq Scan on contact c  (cost=0.00..4456.96 
> rows=228696 width=47) (actual time=0.006..1106.459 rows=229868 loops=1)
>                     ->  Hash  (cost=6024.11..6024.11 rows=228711 
> width=8) (actual time=1742.373..1742.373 rows=0 loops=1)
>                           ->  Seq Scan on account a  
> (cost=0.00..6024.11 rows=228711 width=8) (actual time=0.010..990.597 
> rows=229855 loops=1)
>               ->  Hash  (cost=14040.49..14040.49 rows=1 width=117) 
> (actual time=107911.397..107911.397 rows=0 loops=1)
>                     ->  Nested Loop  (cost=10.34..14040.49 rows=1 
> width=117) (actual time=1185.383..107910.738 rows=110 loops=1)
>                           ->  Nested Loop  (cost=10.34..14037.45 rows=1 
> width=112) (actual time=1185.278..107898.885 rows=550 loops=1)
>                                 ->  Hash Join  (cost=10.34..14033.98 
> rows=1 width=124) (actual time=1185.224..107888.542 rows=110 loops=1)
>                                       Hash Cond: 
> ("outer".fkserviceofferingid = "inner".serviceofferingid)
>                                       ->  Hash Join  
> (cost=7.96..14031.58 rows=1 width=128) (actual time=1184.490..107886.329 
> rows=110 loops=1)
>                                             Hash Cond: 
> ("outer".fkserviceinstancestatusid = "inner".serviceinstancestatusid)
>                                             ->  Nested Loop  
> (cost=6.90..14030.50 rows=1 width=132) (actual time=1184.151..107884.302 
> rows=110 loops=1)
>                                                   Join Filter: 
> ("outer".fkaccountid = "inner".fkaccountid)

Well, here's the step that's killing you:
>                                                   ->  Nested Loop  
> (cost=6.90..14025.09 rows=1 width=116) (actual time=1184.123..107880.635 
> rows=110 loops=1)
>                                                         Join Filter: 
> (("outer".fkaccountid = "inner".fkaccountid) AND 
> ("outer".serviceinstanceid = "inner".serviceinstanceid))
>                                                         ->  Hash Join  
> (cost=3.45..636.39 rows=1 width=95) (actual time=85.524..293.387 
> rows=226 loops=1)
>                                                               Hash 
> Cond: ("outer".fkserviceinstancestatusid = "inner".serviceinstancestatusid)

Unfortunately, the way this query plan came out it's difficult to figure
out what the other input to that nested loop is. But before we get to
that, what do you have join_collapse_limit set to? If it's the default
of 8 then the optimizer is essentially going to follow the join order
you specified when you wrote the view, which could be far from optimal.
It would be worth setting join_collapse_limit high enough so that this
query will get flattened and see what kind of plan it comes up with
then. Note that this could result in an unreasonably-large plan time,
but if it results in a fast query execution we know it's just a matter
of re-ordering things in the query.

Also, it would be best if you could send the results of explain as an
attachement that hasn't been word-wrapped.

>                                                               ->  Hash 
> Join  (cost=2.38..635.29 rows=4 width=87) (actual time=6.894..289.000 
> rows=663 loops=1)
>                                                                     
> Hash Cond: ("outer".fkserviceofferingid = "inner".serviceofferingid)
>                                                                     ->  
> Nested Loop  (cost=0.00..632.75 rows=23 width=91) (actual 
> time=6.176..281.620 rows=663 loops=1)
>                                                                           
> ->  Nested Loop  (cost=0.00..508.26 rows=23 width=13) (actual 
> time=6.138..221.590 rows=663 loops=1)
>                                                                                 
> ->  Index Scan using idx_parameter_value on parameter p  
> (cost=0.00..437.42 rows=23 width=13) (actual time=6.091..20.656 rows=663 
> loops=1)
>                                                                                       
> Index Cond: (value = '099'::text)
>                                                                                       
> Filter: (name = 'countyNo'::text)
>                                                                                 
> ->  Index Scan using idx_serviceinstanceparameter_fkparameterid on 
> serviceinstanceparameter sip  (cost=0.00..3.07 rows=1 width=8) (actual 
> time=0.278..0.288 rows=1 loops=663)
>                                                                                       
> Index Cond: (sip.fkparameterid = "outer".parameterid)
>                                                                           
> ->  Index Scan using pk_serviceinstance_serviceinstanceid on 
> serviceinstance si  (cost=0.00..5.40 rows=1 width=78) (actual 
> time=0.041..0.073 rows=1 loops=663)
>                                                                                 
> Index Cond: (si.serviceinstanceid = "outer".fkserviceinstanceid)
>                                                                     ->  
> Hash  (cost=2.38..2.38 rows=3 width=4) (actual time=0.445..0.445 rows=0 
> loops=1)
>                                                                           
> ->  Hash Join  (cost=1.08..2.38 rows=3 width=4) (actual 
> time=0.314..0.426 rows=1 loops=1)
>                                                                                 
> Hash Cond: ("outer".fkserviceid = "inner".serviceid)
>                                                                                 
> ->  Seq Scan on serviceoffering so  (cost=0.00..1.18 rows=18width=8) 
> (actual time=0.005..0.065 rows=18 loops=1)
>                                                                                 
> ->  Hash  (cost=1.07..1.07 rows=1 width=4) (actual time=0.033..0.033 
> rows=0 loops=1)
>                                                                                       
> ->  Seq Scan on service s  (cost=0.00..1.07 rows=1 width=4) (actual 
> time=0.011..0.016 rows=1 loops=1)
>                                                                                             
> Filter: (servicename = 'alert'::text)
>                                                               ->  Hash  
> (cost=1.06..1.06 rows=1 width=16) (actual time=0.031..0.031 rows=0 loops=1)
>                                                                     ->  
> Seq Scan on serviceinstancestatus sis  (cost=0.00..1.06 rows=1 width=16) 
> (actual time=0.008..0.014 rows=1 loops=1)
>                                                                           
> Filter: (status = 'ACTIVE'::text)
>                                                         ->  Hash Join  
> (cost=3.45..13386.23 rows=165 width=21) (actual time=0.119..461.891 
> rows=3935 loops=226)
>                                                               Hash 
> Cond: ("outer".fkserviceinstancestatusid = "inner".serviceinstancestatusid)
>                                                               ->  Hash 
> Join  (cost=2.38..13382.69 rows=165 width=25) (actual 
> time=0.110..432.555 rows=3935 loops=226)
>                                                                     
> Hash Cond: ("outer".fkserviceofferingid = "inner".serviceofferingid)
>                                                                     ->  
> Nested Loop  (cost=0.00..13373.71 rows=990 width=29) (actual 
> time=0.098..400.805 rows=3935 loops=226)
>                                                                           
> ->  Nested Loop  (cost=0.00..8015.16 rows=990 width=13) (actual 
> time=0.035..267.634 rows=3935 loops=226)
>                                                                                 
> ->  Seq Scan on parameter p  (cost=0.00..4968.81 rows=989 width=13) 
> (actual time=0.008..131.735 rows=3935 loops=226)
>                                                                                       
> Filter: ((name = 'countyState'::text) AND (value = 'FL'::text))
>                                                                                 
> ->  Index Scan using idx_serviceinstanceparameter_fkparameterid on 
> serviceinstanceparameter sip  (cost=0.00..3.07 rows=1 width=8) (actual 
> time=0.015..0.020 rows=1 loops=889310)
>                                                                                       
> Index Cond: (sip.fkparameterid = "outer".parameterid)
>                                                                           
> ->  Index Scan using pk_serviceinstance_serviceinstanceid on 
> serviceinstance si  (cost=0.00..5.40 rows=1 width=16) (actual 
> time=0.012..0.019 rows=1 loops=889310)
>                                                                                 
> Index Cond: (si.serviceinstanceid = "outer".fkserviceinstanceid)
>                                                                     ->  
> Hash  (cost=2.38..2.38 rows=3 width=4) (actual time=0.439..0.439 rows=0 
> loops=1)
>                                                                           
> ->  Hash Join  (cost=1.08..2.38 rows=3 width=4) (actual 
> time=0.310..0.423 rows=1 loops=1)
>                                                                                 
> Hash Cond: ("outer".fkserviceid = "inner".serviceid)
>                                                                                 
> ->  Seq Scan on serviceoffering so  (cost=0.00..1.18 rows=18 width=8) 
> (actual time=0.006..0.065 rows=18 loops=1)
>                                                                                 
> ->  Hash  (cost=1.07..1.07 rows=1 width=4) (actual time=0.035..0.035 
> rows=0 loops=1)
>                                                                                       
> ->  Seq Scan on service s  (cost=0.00..1.07 rows=1 width=4) (actual 
> time=0.013..0.018 rows=1 loops=1)
>                                                                                             
> Filter: (servicename = 'alert'::text)
>                                                               ->  Hash  
> (cost=1.05..1.05 rows=5 width=4) (actual time=0.059..0.059 rows=0 loops=1)
>                                                                     ->  
> Seq Scan on serviceinstancestatus sis  (cost=0.00..1.05 rows=5 width=4) 
> (actual time=0.010..0.029 rows=5 loops=1)
>                                                   ->  Index Scan using 
> pk_serviceinstance_serviceinstanceid on serviceinstance si  
> (cost=0.00..5.40 rows=1 width=16) (actual time=0.009..0.012 rows=1 
> loops=110)
>                                                         Index Cond: 
> (si.serviceinstanceid = "outer".fkserviceinstanceid)
>                                             ->  Hash  (cost=1.05..1.05 
> rows=5 width=4) (actual time=0.055..0.055 rows=0 loops=1)
>                                                   ->  Seq Scan on 
> serviceinstancestatus sis  (cost=0.00..1.05 rows=5 width=4) (actual 
> time=0.008..0.025 rows=5 loops=1)
>                                       ->  Hash  (cost=2.38..2.38 rows=3 
> width=4) (actual time=0.461..0.461 rows=0 loops=1)
>                                             ->  Hash Join  
> (cost=1.08..2.38 rows=3 width=4) (actual time=0.325..0.445 rows=1 loops=1)
>                                                   Hash Cond: 
> ("outer".fkserviceid = "inner".serviceid)
>                                                   ->  Seq Scan on 
> serviceoffering so  (cost=0.00..1.18 rows=18 width=8) (actual 
> time=0.006..0.074 rows=18 loops=1)
>                                                   ->  Hash  
> (cost=1.07..1.07 rows=1 width=4) (actual time=0.044..0.044 rows=0 loops=1)
>                                                         ->  Seq Scan on 
> service s  (cost=0.00..1.07 rows=1 width=4) (actual time=0.022..0.027 
> rows=1 loops=1)
>                                                               Filter: 
> (servicename = 'alert'::text)
>                                 ->  Index Scan using 
> idx_serviceinstanceparameter_fkserviceinstanceid on 
> serviceinstanceparameter sip  (cost=0.00..3.41 rows=5 width=8) (actual 
> time=0.018..0.038 rows=5 loops=110)
>                                       Index Cond: 
> (sip.fkserviceinstanceid = "outer".fkserviceinstanceid)
>                           ->  Index Scan using pk_parameter_parameterid 
> on parameter p  (cost=0.00..3.02 rows=1 width=13) (actual 
> time=0.011..0.012 rows=0 loops=550)
>                                 Index Cond: ("outer".fkparameterid = 
> p.parameterid)
>                                 Filter: (name = 'listingType'::text)
> 
> Total runtime: 113490.582 ms
> (82 rows)
-- 
Jim C. Nasby, Sr. Engineering Consultant      jnasby@pervasive.com
Pervasive Software      http://pervasive.com    work: 512-231-6117
vcard: http://jim.nasby.net/pervasive.vcf       cell: 512-569-9461



^ permalink  raw  reply  [nested|flat] 5+ messages in thread


end of thread, other threads:[~2006-01-11 19:02 UTC | newest]

Thread overview: 5+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2006-01-11 15:03 Postgres8.0 Planner chooses WRONG plan. Pallav Kalva <pkalva@livedatagroup.com>
2006-01-11 15:27 Postgres8.0 planner chooses WRONG plan Pallav Kalva <pkalva@livedatagroup.com>
2006-01-11 16:07 ` Re: Postgres8.0 planner chooses WRONG plan Tom Lane <tgl@sss.pgh.pa.us>
2006-01-11 16:44   ` Re: Postgres8.0 planner chooses WRONG plan Pallav Kalva <pkalva@livedatagroup.com>
2006-01-11 19:02     ` Re: Postgres8.0 planner chooses WRONG plan Jim C. Nasby <jnasby@pervasive.com>

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox