Performance With Joins on Large Tables

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I am having problems performing a join on two large tables.  It seems to only
want to use a sequential scan on the join, but that method seems to be slower
than an index scan.  I've never actually had it complete the sequential scan
because I stop it after 24+ hours.  I've run joins against large tables before
and an index scan was always faster (a few hours at the most).

Here is some information on the two tables:
data=# analyze view_505;
ANALYZE
data=# analyze r3s169;
ANALYZE
data=# \d view_505
              Table "public.view_505"
     Column      |         Type          | Modifiers
------------------+-----------------------+-----------
dsiacctno        | numeric               |
name             | boolean               |
title            | boolean               |
company          | boolean               |
zip4             | boolean               |
acceptcall       | boolean               |
phonedirect      | smallint              |
phonetollfree    | smallint              |
fax              | smallint              |
editdrop         | boolean               |
postsuppress     | boolean               |
firstnameinit    | boolean               |
prefix           | integer               |
crrt             | boolean               |
dpbc             | boolean               |
executive        | integer               |
addressline      | integer               |
multibuyer       | integer               |
activemultibuyer | integer               |
active           | boolean               |
emails           | integer               |
domains          | integer               |
zip1             | character varying(1)  |
zip3             | character varying(3)  |
gender           | character varying(1)  |
topdomains       | bit varying           |
city             | character varying(35) |
state            | character varying(35) |
zip              | character varying(20) |
country          | character varying(30) |
selects          | bit varying           |
files            | integer[]             |
sics             | integer[]             |
custdate         | date                  |
Indexes:
   "view_505_city" btree (city)
   "view_505_dsiacctno" btree (dsiacctno)
   "view_505_state" btree (state)
   "view_505_zip" btree (zip)
   "view_505_zip1" btree (zip1)
   "view_505_zip3" btree (zip3)

data=# \d r3s169
             Table "public.r3s169"
  Column    |          Type          | Modifiers
-------------+------------------------+-----------
dsiacctno   | numeric                |
fileid      | integer                |
customerid  | character varying(20)  |
email       | character varying(100) |
sic2        | character varying(2)   |
sic4        | character varying(4)   |
sic6        | character varying(6)   |
custdate    | date                   |
inqdate     | date                   |
eentrydate  | date                   |
esubdate    | date                   |
efaildate   | date                   |
eunlistdate | date                   |
pentrydate  | date                   |
psubdate    | date                   |
punlistdate | date                   |
pexpiredate | date                   |
lastupdate  | date                   |
emaildrop   | numeric                |
sic8        | character varying(8)   |
Indexes:
   "r3s169_dsiacctno" btree (dsiacctno)

data=# select count(*) from view_505;
  count
-----------
112393845
(1 row)

data=# select count(*) from r3s169;
  count
-----------
285230264
(1 row)


Here is what EXPLAIN says:

data=# EXPLAIN SELECT v.phonedirect, v.editdrop, EXTRACT (EPOCH FROM
v.custdate), EXTRACT (YEAR FROM s.custdate) || '-' || EXTRACT (MONTH
FROM s.custdate) FROM view_505 v INNER JOIN r3s169 s ON v.dsiacctno =
s.dsiacctno;
                                         QUERY PLAN
-----------------------------------------------------------------------------------------------
Merge Join  (cost=293767607.69..305744319.52 rows=285392608 width=11)
  Merge Cond: ("outer".dsiacctno = "inner".dsiacctno)
  ->  Sort  (cost=127304933.87..127585815.71 rows=112352736 width=20)
        Sort Key: v.dsiacctno
        ->  Seq Scan on view_505 v  (cost=100000000.00..104604059.36
rows=112352736 width=20)
  ->  Sort  (cost=166462673.82..167176155.34 rows=285392608 width=17)
        Sort Key: s.dsiacctno
        ->  Seq Scan on r3s169 s  (cost=100000000.00..106875334.08
rows=285392608 width=17)
(8 rows)



I can't really do and EXPLAIN ANALYZE because the query never really finishes.
Also, I use a cursor to loop through the data.  view_505 isn't a pgsql view, its
just how we decided to name the table.  There is a one to many
relationship between
view_505 and r3s169.

Since enable_seqscan is off, my understanding is that in order for the query
planner to user a sequential scan it must think there is no other alternative.
Both sides are indexed and anaylzed, so that confuses me a little.

I tried it on a smaller sample set of the data and it works fine:

data=# select * into r3s169_test from r3s169 limit 1000000;
SELECT
data=# select * into view_505_test from view_505 limit 1000000;
SELECT
data=# create index r3s169_test_dsiacctno on r3s169_test (dsiacctno);
CREATE INDEX
data=# create index view_505_test_dsiacctno on view_505_test (dsiacctno);
CREATE INDEX
data=# analyze r3s169_test;
ANALYZE
data=# analyze view_505_test;
ANALYZE
data=# EXPLAIN SELECT v.phonedirect, v.editdrop, EXTRACT (EPOCH FROM
v.custdate), EXTRACT (YEAR FROM s.custdate) || '-' || EXTRACT (MONTH
FROM s.custdate) FROM view_505_test v INNER JOIN r3s169_test s ON
v.dsiacctno = s.dsiacctno;
                                                  QUERY PLAN
-----------------------------------------------------------------------------------------------------------------
Merge Join  (cost=0.00..1976704.69 rows=1000187 width=11)
  Merge Cond: ("outer".dsiacctno = "inner".dsiacctno)
  ->  Index Scan using view_505_test_dsiacctno on view_505_test v
(cost=0.00..1676260.67 rows=999985 width=20)
  ->  Index Scan using r3s169_test_dsiacctno on r3s169_test s
(cost=0.00..1089028.66 rows=1000186 width=17)
(4 rows)


Is there anything I'm missing that is preventing it from using the index?  It
just seems weird to me that other joins like this work fine and fast
with indexes,
but this one won't.


[Postgresql General]     [Postgresql PHP]     [PHP Users]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Books]     [PHP Databases]     [Yosemite]

  Powered by Linux