Re: JOIN not being calculated correctly - Mailing list pgsql-sql

From Scott Pederick
Subject Re: JOIN not being calculated correctly
Date
Msg-id 000501c4cf49$31c346e0$e1f9f4dc@boblaptop
Whole thread Raw
In response to JOIN not being calculated correctly  ("Scott Pederick" <scott@pederick.com>)
Responses Re: JOIN not being calculated correctly
List pgsql-sql
Hi Andrew,

Thanks for your response - sorry it's taken so long to reply, I've been out
of contact for a while.

Still can't fathom why it's not using an index scan on the jobs table..

: Posting the EXPLAIN is a good, an EXPLAIN ANALYZE would be better
: (assuming your dataset is small enough for it to complete in this
: lifetime). You also need to include the following information:
:
: 1) The schema involved, including information about indexes being used.

Here's the EXPLAIN ANALYZE, schemas and indexes:

Quarry=> EXPLAIN ANALYZE SELECT Customers.CustomerId, Jobs.JobId FROM
Customers INNER JOIN Jobs USING (CustomerId);                                                     QUERY PLAN
----------------------------------------------------------------------------
------------------------------------------Hash Join  (cost=78.54..7924.71 rows=70727 width=8) (actual
time=50.000..21941.000 rows=70727 loops=1)  Hash Cond: ("outer".customerid = "inner".customerid)  ->  Seq Scan on jobs
(cost=0.00..6785.27rows=70727 width=8) (actual
 
time=40.000..21040.000 rows=70727 loops=1)  ->  Hash  (cost=76.03..76.03 rows=1003 width=4) (actual
time=10.000..10.000 rows=0 loops=1)        ->  Seq Scan on customers  (cost=0.00..76.03 rows=1003 width=4)
(actual time=0.000..0.000 rows=1003 loops=1)Total runtime: 22292.000 ms
(6 rows)


Customers
---
CREATE TABLE customers (   customerid serial NOT NULL,   account character varying(6) DEFAULT ''::character varying NOT
NULL,  businessname character varying(40) DEFAULT ''::character varying NOT
 
NULL,   address character varying(30) DEFAULT ''::character varying NOT NULL,   suburb character varying(30) DEFAULT
''::charactervarying NOT NULL,   postcode character varying(4) DEFAULT ''::character varying NOT NULL,   state
character(3)DEFAULT ''::bpchar NOT NULL,   mobile character varying(14) DEFAULT ''::character varying NOT NULL,   fax
charactervarying(14) DEFAULT ''::character varying NOT NULL,   acctitle character varying(4) DEFAULT ''::character
varyingNOT NULL,   accfirst character varying(14) DEFAULT ''::character varying NOT NULL,   acclast character
varying(14)DEFAULT ''::character varying NOT NULL,   accphone character varying(14) DEFAULT ''::character varying NOT
NULL,  accfax character(1) DEFAULT ''::bpchar NOT NULL,   accmobile character varying(14) DEFAULT ''::character varying
NOTNULL,   alttitle character varying(4) DEFAULT ''::character varying NOT NULL,   altfirst character varying(14)
DEFAULT''::character varying NOT NULL,   altlast character varying(14) DEFAULT ''::character varying NOT NULL,
currentnumeric(10,2) DEFAULT 0 NOT NULL,   aged30 numeric(10,2) DEFAULT 0 NOT NULL,   aged60 numeric(10,2) DEFAULT 0
NOTNULL,   aged90 numeric(10,2) DEFAULT 0 NOT NULL,   ytd numeric(10,2) DEFAULT 0 NOT NULL,   pg character(1) DEFAULT
''::bpcharNOT NULL,   acclimit character varying(14) DEFAULT ''::character varying NOT NULL,   accauto character(1)
DEFAULT''::bpchar NOT NULL,   text text DEFAULT ''::text NOT NULL,   fee character(1) DEFAULT ''::bpchar NOT NULL,
gstcharacter(1) DEFAULT ''::bpchar NOT NULL,   stop character(1) DEFAULT ''::bpchar NOT NULL
 
);

Customers - Indexes
---
customers_pkey PRIMARY KEY (customerid);
UNIQUE INDEX customers_account ON customers USING btree (account);



Jobs
---
CREATE TABLE jobs (   jobid serial NOT NULL,   customerid integer,   quarryid integer,   producttypeid integer,
invoiceidinteger,   salesid integer,   orderid character varying(15) DEFAULT ''::character varying NOT NULL,   jobdate
date,  contactname character varying(40) DEFAULT ''::character varying NOT
 
NULL,   businessname character varying(40) DEFAULT ''::character varying NOT
NULL,   address character varying(30) DEFAULT ''::character varying NOT NULL,   suburb character varying(30) DEFAULT
''::charactervarying NOT NULL,   phone character varying(14) DEFAULT ''::character varying NOT NULL,   melway character
varying(4)DEFAULT ''::character varying NOT NULL,   melxy character(3) DEFAULT ''::bpchar NOT NULL,   quarryorder
numeric(10,2)DEFAULT 0 NOT NULL,   quarrypickup numeric(10,2) DEFAULT 0 NOT NULL,   quarryprice numeric(10,2) DEFAULT 0
NOTNULL,   transport numeric(10,2) DEFAULT 0 NOT NULL,   margin numeric(10,2) DEFAULT 0 NOT NULL,   unit character(1)
DEFAULT''::bpchar NOT NULL,   done character(1) DEFAULT ''::bpchar NOT NULL,   xno character varying(10) DEFAULT
''::charactervarying NOT NULL,   mzone character(1) DEFAULT ''::bpchar NOT NULL,   invoice numeric(10,2) DEFAULT 0 NOT
NULL,  drivercomment character varying(12) DEFAULT ''::character varying NOT
 
NULL   text text DEFAULT ''::text NOT NULL,   gst numeric(10,2) DEFAULT 0 NOT NULL,   distance numeric(7,2) DEFAULT 0
NOTNULL,   productdefinitionid integer,   customerprice numeric(10,2) DEFAULT 0 NOT NULL
 
);

Jobs Keys/Indexes
---
jobs_pkey PRIMARY KEY (jobid);
INDEX jobs_customerid ON jobs USING btree (customerid);
INDEX jobs_jobdate ON jobs USING btree (jobdate);
INDEX jobs_quarryid ON jobs USING btree (quarryid);

CONSTRAINT jobs_customerid_fkey FOREIGN KEY (customerid) REFERENCES
customers(customerid) ON UPDATE RESTRICT ON DELETE RESTRICT;
CONSTRAINT jobs_invoiceid_fkey FOREIGN KEY (invoiceid) REFERENCES
invoices(invoiceid) ON UPDATE RESTRICT ON DELETE RESTRICT;
ADD CONSTRAINT jobs_productdefinitionid_fkey FOREIGN KEY
(productdefinitionid) REFERENCES producttypes(producttypeid) ON UPDATE
RESTRICT;
CONSTRAINT jobs_producttypeid_fkey FOREIGN KEY (producttypeid) REFERENCES
producttypes(producttypeid) ON UPDATE RESTRICT ON DELETE RESTRICT;
CONSTRAINT jobs_quarryid_fkey FOREIGN KEY (quarryid) REFERENCES
quarries(quarryid) ON UPDATE RESTRICT ON DELETE RESTRICT;
CONSTRAINT jobs_salesid_fkey FOREIGN KEY (salesid) REFERENCES sales(salesid)
ON UPDATE RESTRICT ON DELETE RESTRICT;



: 2) Have you vacuumed / analyzed the tables involved recently?

Yes, I ran "VACUUM ANALYZE" on both table before I started.


: 3) Have you modified the stats on any of the tables / columns involve or
: are you using defaults?

I'm using the defaults...

Thanks in advance to anyone who has taken the time to wade through this
one... :)

Scott

:
: Drew
:
:
: Scott Pederick wrote:
: | Hi all!
: |
: | I'm having a problem with Postgresql 8.0.0-beta4 on a Win2K machine and
a
: | particular join.
: |
: | I've got two tables - a list of customers and jobs they've had. A
customer
: | can have multiple jobs.
: |
: | The query always scans the entire jobs table for each customer - I need
it
: | the other way around so I can get a list of the customers who have at
: least
: | one job.
: |
: | The EXPLAIN shows the jobs table is being scanned for some reason:
: |
: | Quarry=# EXPLAIN SELECT Customers.CustomerId, Jobs.JobId FROM Customers
: | INNER JOIN Jobs USING (CustomerId);
: |                                QUERY PLAN
:
| -------------------------------------------------------------------------
: |  Hash Join  (cost=78.54..4908.71 rows=70727 width=8)
: |    Hash Cond: ("outer".customerid = "inner".customerid)
: |    ->  Seq Scan on jobs  (cost=0.00..3769.27 rows=70727 width=8)
: |    ->  Hash  (cost=76.03..76.03 rows=1003 width=4)
: |          ->  Seq Scan on customers  (cost=0.00..76.03 rows=1003 width=4)
: | (5 rows)
: |
: |
: |
: | Even if I reverse the JOIN I get the exact same result:
: |
: | Quarry=# EXPLAIN SELECT Customers.CustomerId, Jobs.JobId FROM Jobs INNER
: | JOIN Customers USING (CustomerId);
: |                                QUERY PLAN
:
| -------------------------------------------------------------------------
: |  Hash Join  (cost=78.54..4908.71 rows=70727 width=8)
: |    Hash Cond: ("outer".customerid = "inner".customerid)
: |    ->  Seq Scan on jobs  (cost=0.00..3769.27 rows=70727 width=8)
: |    ->  Hash  (cost=76.03..76.03 rows=1003 width=4)
: |          ->  Seq Scan on customers  (cost=0.00..76.03 rows=1003 width=4)
: | (5 rows)
: |
: |
: | How can I force it to operate as I need it to? It seems the query
: engine is
: | a little smarter than it needs to be.
: |
: | If anyone can shed some light on this problem, it would be greatly
: | appreciated. I've taken it as far as I can and don't really know where
to
: | move from here.
:
:
: - --
: Andrew Hammond    416-673-4138    ahammond@ca.afilias.info
: Database Administrator, Afilias Canada Corp.
: CB83 2838 4B67 D40F D086 3568 81FC E7E5 27AF 4A9A
: -----BEGIN PGP SIGNATURE-----
: Version: GnuPG v1.2.5 (GNU/Linux)
:
: iD8DBQFBh9YQgfzn5SevSpoRAg0LAKCg5K7IccFIOvdTc8DEl2YaUMcUCgCfRt2Q
: CI1Vo6yxHkrWcoTQMQ/EvOw=
: =m15B
: -----END PGP SIGNATURE-----
:
: ---------------------------(end of broadcast)---------------------------
: TIP 3: if posting/reading through Usenet, please send an appropriate
:       subscribe-nomail command to majordomo@postgresql.org so that your
:       message can get through to the mailing list cleanly
:



pgsql-sql by date:

Previous
From: Rodrigo Carvalhaes
Date:
Subject: Re: How to get the max on a char column?
Next
From: Tom Lane
Date:
Subject: Re: JOIN not being calculated correctly