Re: Slow views

From: Stephan Szabo <sszabo(at)megazone(dot)bigpanda(dot)com>
To: davidn-postgres(at)rebel(dot)net(dot)au
Cc: pgsql-bugs(at)postgresql(dot)org
Subject: Re: Slow views
Date: 2004-07-16 19:33:00
Message-ID: 20040716121720.C75128@megazone.bigpanda.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs


On Sat, 10 Jul 2004 davidn-postgres(at)rebel(dot)net(dot)au wrote:

> I know this has been discussed many times before but I'm not entirely
> satisfied with the answer, which I understand is "views are essentially
> macros". Despite that Postgres is producing the correct output, I hope
> you'll all agree that the performance issue is serious enough to call
> this a "bug."
>
> I'm running Postgres 7.4.3 installed on Fedora Core 1 (i386) from rpms
> downloaded from ftp.postgres.org.
>
> I've got a view defined as:
>
> CREATE VIEW stock_exp_v AS
> SELECT stock_code, barcode, title, supplier.description AS supplier,
> format.description AS format, rating.description AS rating,
> genre_list(stock_code) AS genre, release_date, price, srp
> FROM stock
> LEFT JOIN supplier USING (supplier_code)
> LEFT JOIN format USING (format_code)
> LEFT JOIN rating USING (rating_code);
>
>
> When I use the view in a join the query takes 52 seconds, for example:
>
> SELECT trim(stock_code), barcode, title, supplier, format, rating, genre,
> release_date, o.price, o.srp, quantity
> FROM order_lines o
> LEFT JOIN stock_exp_v USING (stock_code);
>
> Time: 52110.369 ms
>
> When I expand the view by hand it takes only 27 milliseconds:
>
> SELECT trim(stock_code), barcode, title, supplier.description,
> format.description, rating.description, genre_list(o.stock_code),
> release_date, o.price, o.srp, quantity
> FROM order_lines o
> LEFT JOIN stock USING (stock_code)
> LEFT JOIN supplier USING (supplier_code)
> LEFT JOIN format USING (format_code)
> LEFT JOIN rating USING (rating_code);

That's not expanding the view. Expanding the view would be something
like:

select trim(stock_code), barcode, title, supplier, format, rating, genre,
release_date, o.price, o.srp, quantity
FROM order_lines o
LEFT JOIN
( select stock_code, barcode, title, supplier.description as supplier,
format.description AS format, rating.description AS rating,
genre_list(stock_code) AS genre, release_date, price, srp
FROM stock LEFT JOIN supplier USING (supplier_code)
LEFT JOIN format USING (format_code)
LEFT JOIN rating USING (rating_code) ) stock_exp_v USING (stock_code)

You also did an optimization, removing the subquery which PostgreSQL
isn't.

The problem is that while I believe it was safe for the query above
because it uses USING throughout, in general it is not necessarily safe,
because the queries may have different results if a join condition in the
view could return true for NULL values in stock.

For example, I think
A LEFT JOIN B USING (blah) LEFT JOIN C ON (B.bval = C.bval or B.bval is
null)
is different from
A LEFT JOIN (B LEFT JOIN C ON (B.bval = C.bval or B.bval is null)) USING
(blah)

In response to

  • Slow views at 2004-07-10 10:52:29 from davidn-postgres

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Stephan Szabo 2004-07-16 20:16:04 Re: Replace function BUG
Previous Message Bruce Momjian 2004-07-15 14:32:36 Re: SELECT DISTINCT on boxes