Thread: Poor performance on a right join

Poor performance on a right join

From
sarloc@jevic.com (Carmen)
Date:
When doing a join query I am getting a responce time of 3 seconds. The
callhist table has 66000 rows and the phone table has 10000 rows. I
have an indexes on callhist.call_date, callhist.operator_id,
phone.phone, & phone.cust_code. Here's the SQL
SELECT a.CALL_DATE, a.OPERATOR_ID, a.CUST_CODE FROM PHONE as b right
join CALLHIST as a on (a.CUST_CODE=b.CUST_CODE) where (b.PHONE =
'555-555-5555') order by a.call_date desc;
The postgres db is running on a 2 P3 700 processor server with 1GB of
ram running Red Hat Linux 7.3. I am running PostgreSQL 7.2.2

Why is the query taking so long? What can I do to help the
performance?

Thanks in advance,

Carmen


Re: Poor performance on a right join

From
dev@archonet.com
Date:
> When doing a join query I am getting a responce time of 3 seconds. The
> callhist table has 66000 rows and the phone table has 10000 rows. I
> have an indexes on callhist.call_date, callhist.operator_id,
> phone.phone, & phone.cust_code. Here's the SQL
> SELECT a.CALL_DATE, a.OPERATOR_ID, a.CUST_CODE FROM PHONE as b right
> join CALLHIST as a on (a.CUST_CODE=b.CUST_CODE) where (b.PHONE =
> '555-555-5555') order by a.call_date desc;
> The postgres db is running on a 2 P3 700 processor server with 1GB of
> ram running Red Hat Linux 7.3. I am running PostgreSQL 7.2.2
>
> Why is the query taking so long? What can I do to help the
> performance?

We'll need the output of EXPLAIN ANALYSE SELECT ...
Perhaps table definitions too.

- Richard Huxton


Re: Poor performance on a right join

From
Carmen Sarlo
Date:
<p><font size="2">Here's the EXPLAIN output:</font><p><font size="2">EXPLAIN ANALYZE SELECT a.CALL_DATE, a.OPERATOR_ID,
a.CUST_CODEFROM </font><br /><font size="2">PHONE as b right join CALLHIST as a on (a.CUST_CODE=b.CUST_CODE) where
(b.PHONE</font><br /><font size="2">= '847-478-2100') order by a.call_date desc;</font><br /><font size="2">NOTICE: 
QUERYPLAN:</font><p><font size="2">Sort  (cost=14320.04..14320.04 rows=60466 width=68) (actual
time=5104.37..5104.3</font><br/><font size="2">8 rows=23 loops=1)</font><br /><font size="2">  ->  Merge Join 
(cost=0.00..8157.88rows=60466 width=68) (actual time=1396.24.</font><br /><font size="2">.5104.08 rows=23
loops=1)</font><br/><font size="2">        ->  Index Scan using phone_custcode_idx on phone b  (cost=0.00..345.34
r</font><br/><font size="2">ows=11395 width=28) (actual time=0.28..473.16 rows=11402 loops=1)</font><br /><font
size="2">       ->  Index Scan using callhist_cust_idx on callhist a  (cost=0.00..4667.4</font><br /><font
size="2">8rows=60466 width=40) (actual time=0.37..3717.76 rows=254386 loops=1)</font><br /><font size="2">Total
runtime:5104.58 msec</font><p><font size="2">EXPLAIN</font><p><font size="2">The table definitions are:</font><br
/><fontsize="2">callhist (</font><br /><font size="2">  callhist_id int4 DEFAULT
nextval('"callhist_callhist_id_seq"'::text)NOT NULL, </font><br /><font size="2">  name char(25) NOT NULL, </font><br
/><fontsize="2">  cust_code char(8) NOT NULL, </font><br /><font size="2">  action char(1) NOT NULL, </font><br /><font
size="2"> call_date timestamp NOT NULL, </font><br /><font size="2">  operator_id char(16) NOT NULL, </font><br /><font
size="2"> notes text, </font><br /><font size="2">  CONSTRAINT callhist_pkey PRIMARY KEY (callhist_id)</font><br
/><fontsize="2">) WITH OIDS;</font><p><font size="2">phone (</font><br /><font size="2">  phone char(12) NOT NULL,
</font><br/><font size="2">  cust_code char(8) NOT NULL, </font><br /><font size="2">  CONSTRAINT phone_pkey PRIMARY
KEY(phone, cust_code)</font><br /><font size="2">) WITH OIDS;</font><br /><p><font size="2">Carmen</font><p><font
size="2">-----OriginalMessage-----</font><br /><font size="2">From: dev@archonet.com [<a
href="mailto:dev@archonet.com">mailto:dev@archonet.com</a>]</font><br/><font size="2">Sent: Friday, March 14, 2003 3:13
AM</font><br/><font size="2">To: sarloc@jevic.com</font><br /><font size="2">Cc: pgsql-sql@postgresql.org</font><br
/><fontsize="2">Subject: Re: [SQL] Poor performance on a right join</font><br /><p><font size="2">> When doing a
joinquery I am getting a responce time of 3 seconds. The</font><br /><font size="2">> callhist table has 66000 rows
andthe phone table has 10000 rows. I</font><br /><font size="2">> have an indexes on callhist.call_date,
callhist.operator_id,</font><br/><font size="2">> phone.phone, & phone.cust_code. Here's the SQL</font><br
/><fontsize="2">> SELECT a.CALL_DATE, a.OPERATOR_ID, a.CUST_CODE FROM PHONE as b right</font><br /><font
size="2">>join CALLHIST as a on (a.CUST_CODE=b.CUST_CODE) where (b.PHONE =</font><br /><font size="2">>
'555-555-5555')order by a.call_date desc;</font><br /><font size="2">> The postgres db is running on a 2 P3 700
processorserver with 1GB of</font><br /><font size="2">> ram running Red Hat Linux 7.3. I am running PostgreSQL
7.2.2</font><br/><font size="2">></font><br /><font size="2">> Why is the query taking so long? What can I do to
helpthe</font><br /><font size="2">> performance?</font><p><font size="2">We'll need the output of EXPLAIN ANALYSE
SELECT...</font><br /><font size="2">Perhaps table definitions too.</font><p><font size="2">- Richard Huxton</font> 

Re: Poor performance on a right join

From
Tom Lane
Date:
Carmen Sarlo <SarloC@Jevic.com> writes:
> EXPLAIN ANALYZE SELECT a.CALL_DATE, a.OPERATOR_ID, a.CUST_CODE FROM 
> PHONE as b right join CALLHIST as a on (a.CUST_CODE=b.CUST_CODE) where
> (b.PHONE = '847-478-2100') order by a.call_date desc;

This query is rather pointless as-is: the WHERE clause will eliminate
any null-extended rows produced by the RIGHT JOIN (because null b.PHONE
cannot satisfy the '=' condition).  So you may as well reduce the right
join to a plain join.  That will result in a much better plan, because
then the WHERE clause can be pushed down to the scan of b.

7.4 will be bright enough to make that deduction by itself, but 7.3 is
not, and certainly not 7.2 ...
        regards, tom lane


Re: Poor performance on a right join

From
dev@archonet.com
Date:
> Here's the EXPLAIN output:
>
> EXPLAIN ANALYZE SELECT a.CALL_DATE, a.OPERATOR_ID, a.CUST_CODE FROM
> PHONE as b right join CALLHIST as a on (a.CUST_CODE=b.CUST_CODE) where
> (b.PHONE
> = '847-478-2100') order by a.call_date desc;
> NOTICE:  QUERY PLAN:
>
> Sort  (cost=14320.04..14320.04 rows=60466 width=68) (actual
> time=5104.37..5104.3
> 8 rows=23 loops=1)
>   ->  Merge Join  (cost=0.00..8157.88 rows=60466 width=68) (actual
> time=1396.24.
> .5104.08 rows=23 loops=1)
>         ->  Index Scan using phone_custcode_idx on phone b
> (cost=0.00..345.34 r
> ows=11395 width=28) (actual time=0.28..473.16 rows=11402 loops=1)
>         ->  Index Scan using callhist_cust_idx on callhist a
> (cost=0.00..4667.4
> 8 rows=60466 width=40) (actual time=0.37..3717.76 rows=254386 loops=1)
> Total runtime: 5104.58 msec

I might be wrong, but it looks like the join is happening before filtering
on the phone number (rows=254386). What happens if you don't use and
explicit join:
...WHERE a.CUST_CODE=b.CUST_CODE AND b.PHONE = '847-478-2100'...

- Richard Huxton


Re: Poor performance on a right join

From
Carmen Sarlo
Date:
<p><font size="2">I found that when I do an inner join, I get better performance.</font><p><font
size="2">Carmen</font><br/><p><font size="2">-----Original Message-----</font><br /><font size="2">From: Tom Lane [<a
href="mailto:tgl@sss.pgh.pa.us">mailto:tgl@sss.pgh.pa.us</a>]</font><br/><font size="2">Sent: Monday, March 17, 2003
3:31PM</font><br /><font size="2">To: Carmen Sarlo</font><br /><font size="2">Cc: 'dev@archonet.com';
pgsql-sql@postgresql.org</font><br/><font size="2">Subject: Re: [SQL] Poor performance on a right join </font><br
/><p><fontsize="2">Carmen Sarlo <SarloC@Jevic.com> writes:</font><br /><font size="2">> EXPLAIN ANALYZE SELECT
a.CALL_DATE,a.OPERATOR_ID, a.CUST_CODE FROM </font><br /><font size="2">> PHONE as b right join CALLHIST as a on
(a.CUST_CODE=b.CUST_CODE)where</font><br /><font size="2">> (b.PHONE = '847-478-2100') order by a.call_date
desc;</font><p><fontsize="2">This query is rather pointless as-is: the WHERE clause will eliminate</font><br /><font
size="2">anynull-extended rows produced by the RIGHT JOIN (because null b.PHONE</font><br /><font size="2">cannot
satisfythe '=' condition).  So you may as well reduce the right</font><br /><font size="2">join to a plain join.  That
willresult in a much better plan, because</font><br /><font size="2">then the WHERE clause can be pushed down to the
scanof b.</font><p><font size="2">7.4 will be bright enough to make that deduction by itself, but 7.3 is</font><br
/><fontsize="2">not, and certainly not 7.2 ...</font><p>                        <font size="2">regards, tom lane</font>