Re: Poor performance when using a window function in a view - Mailing list pgsql-general

From Chris Hanks
Subject Re: Poor performance when using a window function in a view
Date
Msg-id CAK7KUdCx56qVWHb95--Re4fnDra5o_H6o=69w9hw19Le-MBhFg@mail.gmail.com
Whole thread Raw
In response to Re: Poor performance when using a window function in a view  (Merlin Moncure <mmoncure@gmail.com>)
List pgsql-general
On Wed, Feb 27, 2013 at 10:18 PM, Merlin Moncure <mmoncure@gmail.com> wrote:

> On Wed, Feb 27, 2013 at 8:22 PM, Chris Hanks
> <christopher.m.hanks@gmail.com> wrote:
> > Hi. Sorry if this is repetitive, I tried posting to pgsql-performance
> first
> > but I think it got stuck in moderation.
> >
> > I'm trying to create a view that uses a window function, but it seems
> that
> > Postgres is unable to optimize it. Here's a reproduction of my situation
> > with 9.2.2:
> >
> > ---
> >
> > drop table if exists values cascade;
> >
> > create table values (
> >   fkey1 integer not null,
> >   fkey2 integer not null,
> >   fkey3 integer not null,
> >   value float not null,
> >   constraint values_pkey primary key (fkey1, fkey2, fkey3)
> > );
> >
> > -- This is kind of hacky, but it roughly resembles the size and
> distribution
> > of my dataset.
> > insert into values select distinct on (fkey1, fkey2, fkey3)
> >   i / 12 + 1 as fkey1,
> >   i % 4 + 1 as fkey2,
> >   ceil(random() * 10) as fkey3,
> >   random() * 2 - 1 as value from generate_series(0, 199999) i;
> >
> > create or replace view values_view as
> > select fkey1, fkey3,
> >   (derived1 / max(derived1) over (partition by fkey1)) as derived1,
> >   (derived2 / sum(derived1) over (partition by fkey1)) as derived2
> > from (
> >   select fkey1, fkey3,
> >     cast(sum((case when (value > 0.0) then 4 else 1 end)) as double
> > precision) as derived1,
> >     sum((case when (value > 0.0) then (value * 4) else (value + 1) end))
> as
> > derived2
> >   from values
> >   group by fkey1, fkey3
> > ) as t1;
> >
> > -- This query requires a sequential scan on values, though all the data
> it
> > needs could be found much more efficiently with an index scan.
> > explain analyze select * from values_view where fkey1 = 1263;
> >
> > ---
> >
> > Can anyone suggest a way to rewrite this query? Or if postgres isn't
> capable
> > of optimizing this right now, is there a workaround of some kind? This
> is a
> > view I'd like to be able to join a smaller table against.
>
> this comes up a lot. only way to expose as a view is to push the query
> into a set returning function which you then wrap into a view.
> downside is that any query except on fkey1/fkey 2 will have to fully
> materialize view.
>
> merlin
>

What would that look like? I've googled around for an example of what
you're talking about, but I'm not finding anything. I think I know how to
write a SQL function that will return a set of rows given a fkey1 value,
but I don't see how I'd turn that into a view...?

Thanks!

pgsql-general by date:

Previous
From: Ken Tanzer
Date:
Subject: Re: Similarity Search with Wildcards
Next
From: Tom Lane
Date:
Subject: Re: Poor performance when using a window function in a view