Conditional JOINs ?

From: "Leon Mergen" <leon(at)solatis(dot)com>
To: pgsql-general(at)postgresql(dot)org
Subject: Conditional JOINs ?
Date: 2008-03-18 19:06:33
Message-ID: 5eaaef180803181206g10643404g1c36173925e379c4@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

Hello,

I'm currently camping with a bit of a problem -- i have a common
requests table, and based on an entry's type, I need to join a
specific other table. Consider this database layout:

###########################
-- table where all common request data is stored
CREATE TABLE log.requests (
id BIGSERIAL,
type SMALLINT NOT NULL,
timestamp INTEGER NOT NULL,
-- all kinds of common data
)

-- only rows where log.requests.type = 1
CREATE TABLE log.requests1 (
request_id BIGINT NOT NULL
)

-- only rows where log.requests.type = 2
CREATE TABLE log.requests2 (
request_id BIGINT NOT NULL
)

etc (about 10 different types)

the current VIEW:
CREATE VIEW requests_view AS
SELECT * FROM log.requests LEFT JOIN log.requests1 ON
(log.requests.id = log.requests1.request_id) LEFT JOIN log.requests2
ON (log.requests.id = log.requests2.request_id) -- etc
###########################

As you can see, if the requests table gets a bit large (50mil+ rows)
and when there are many different types, there will be a lot of wasted
JOINs.

Now, based on a previous post on the PostgreSQL mailing list
[http://archives.postgresql.org/pgsql-general/2007-11/msg00723.php] I
came up with this solution:

###########################
-- table where all common request data is stored
CREATE TABLE log.requests (
id BIGSERIAL,
type SMALLINT NOT NULL,
ref1 BIGINT CHECK (type = 1) = (ref1 IS NOT NULL)),
ref2 BIGINT CHECK (type = 2) = (ref2 IS NOT NULL)),
timestamp INTEGER NOT NULL,
-- all kinds of common data
)

-- only rows where log.requests.type = 1
CREATE TABLE log.requests1 (
request_id BIGINT NOT NULL
)

-- only rows where log.requests.type = 2
CREATE TABLE log.requestsz2 (
request_id BIGINT NOT NULL
)

etc (about 10 different types)

the current VIEW:
CREATE VIEW requests_view AS
SELECT * FROM log.requests LEFT JOIN log.requests1 ON
(log.requests.ref1 = log.requests1.request_id) LEFT JOIN log.requests2
ON (log.requests.ref2 = log.requests2.request_id) -- etc
###########################

Now, in my theory, you would say that if postgresql encounters ref1 =
NULL, it will not attempt to JOIN the log.requests1 table. However,
I've been told that because the PostgreSQL planner doesn't know that
ref1 (or any other refX for that matter) is NULL, it will attempt to
JOIN all tables for all rows.

Is this true, and if so.. is there a workaround for this (perhaps that
my database design is flawed) ?

Regards,

Leon Mergen

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Alban Hertroys 2008-03-18 19:35:34 Re: Conditional JOINs ?
Previous Message Erik Jones 2008-03-18 18:50:49 Re: Get index information from information_schema?