Re: Avoiding duplication of code via views -- slower? How do people typically do this?

From: Chris Travers <chris(dot)travers(at)gmail(dot)com>
To: Joe Van Dyk <joe(at)tanga(dot)com>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Avoiding duplication of code via views -- slower? How do people typically do this?
Date: 2013-02-15 07:42:58
Message-ID: CAKt_ZfvE0AYcZAQYVYHLnGxg4DPM34O8D5YtHzk2cewjYHKQPw@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

On Thu, Feb 14, 2013 at 4:32 PM, Joe Van Dyk <joe(at)tanga(dot)com> wrote:

> See
> https://gist.github.com/joevandyk/4957646/raw/86d55472ff8b5a4a6740d9c673d18a7005738467/gistfile1.txtfor the code.
>
> I have promotions(id, end_at, quantity) and promotion_usages(promotion_id).
>
> I have a couple of things I typically want to retrieve, and I'd like those
> things to be composable. In this case, finding recently-expired
> promotions, finding promotions that have a quantity of one, and finding
> promotions that were used.
>
> My approach is to put these conditions into views, then I can join against
> each one. But that approach is much slower than inlining all the code.
>
> How is this typically done?
>

First I am not usually a fan of trying to reduce code duplication by using
views. In general, my experience is that this makes it very easy to make
things slower, and it adds unexpected optimization hedges in unexpected
places.

Your problem here seems to be of this sort. You are joining together two
views in order to add filters. These operations are not really guaranteed
to be the same and so you have an unexpected optimization fence.

My general rule of thumb is to consider moving inline views and WITH
clauses into views as needed.

Now I think there are a bunch of ways to accomplish what you are trying to
do here.

At the risk of jumping straight ahead into advanced functionality and the
accusations that I am making use of magic wands, I will suggest an
object-relational approach to reducing code duplication. This would be to
eliminate most your filter views and make use instead of table methods.

CREATE FUNCTION recently_expired(promotion) returns bool language sql
immutable as
$$
select $1.ended at > now() - '30 days'::interval;
$$;

CREATE FUNCTION is_one_time(promotion) returns bool language sql immutable
as
$$
select $1.quantity = 1;
$$;

The one thing is you'd probably have to manually write in your join against
promotion_uses to make that effective, But you could instead do:

select p.id from promotions p join promotion_usages pu on pu.promotion_id = p.id

where p.is_one_time and p.recently_expired;

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Albe Laurenz 2013-02-15 08:38:38 Re: Immutable functions, Exceptions and the Query Optimizer
Previous Message Joe Van Dyk 2013-02-15 07:00:26 Re: Avoiding duplication of code via views -- slower? How do people typically do this?