I appear to have been able to replicate what you are talking about, but
it required explicitly binding the order by in different ways. See
attached files.

William King
Senior Engineer
Quentus Technologies, INC
1037 NE 65th St Suite 273
Seattle, WA 98115
Main:   (877) 211-9337
Office: (206) 388-4772
Cell:   (253) 686-5518
william.k...@quentustech.com

On 05/26/2013 02:22 AM, Stefan Keller wrote:
> Yes, it actually does, but the planner chooses a seq scan to prepare for that.
> 
> -S.
> 
> 2013/5/26 William King <william.k...@quentustech.com>:
>> Could this scenario not be handled by a step that orders the two tables
>> independently, then for the view interleaves the presorted results?
>> Merging two sorted sets into a single sorted set is usually a trivial
>> task, and it could still take advantage of the existing indexes.
>>
>> William King
>> Senior Engineer
>> Quentus Technologies, INC
>> 1037 NE 65th St Suite 273
>> Seattle, WA 98115
>> Main:   (877) 211-9337
>> Office: (206) 388-4772
>> Cell:   (253) 686-5518
>> william.k...@quentustech.com
>>
>> On 05/25/2013 05:35 PM, Stefan Keller wrote:
>>> Hi
>>>
>>> I've encountered a fundamental problem which - to me - can only be
>>> solved with an (future/possible) real index on views in PostgreSQL
>>> (like the exist already in MS SQL Server and Ora):
>>>
>>> Given following schema:
>>>
>>> 1. TABLE a and TABLE b, each with INDEX on attribute geom.
>>>
>>> 2. A VIEW with union:
>>>
>>> CREATE VIEW myview AS
>>>   SELECT * FROM a
>>>   UNION
>>>   SELECT * FROM b;
>>>
>>> 3. And a simple query with KNN index and a coordinate "mypos" :
>>>
>>> SELECT * FROM myview
>>> ORDER BY ST_Geomfromtext(mypos) <-> myview.geom
>>>
>>> Now, the problem is, that for the "order by" it is not enough that
>>> each on the two tables calculate the ordering separately: We want a
>>> total ordering over all involved tables!
>>>
>>> In fact, the planner realizes that and chooses a seq scan over all
>>> tuples of table a and b - which is slow and suboptimal!
>>>
>>> To me, that's a use case where we would wish to have a distinct index on 
>>> views.
>>>
>>> Any opinions on this?
>>>
>>> Yours, Stefan
>>>
>>>
>>
>>
>> --
>> Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
>> To make changes to your subscription:
>> http://www.postgresql.org/mailpref/pgsql-hackers
quentusrex=# \i sql/view_index_union.sql
CREATE TABLE
CREATE INDEX
CREATE TABLE
CREATE INDEX
INSERT 0 50000
INSERT 0 50000
CREATE VIEW
                                                         QUERY PLAN             
                                            
----------------------------------------------------------------------------------------------------------------------------
 Index Scan using named_a_idx on a  (cost=0.41..4329.78 rows=51291 width=36) 
(actual time=0.078..33.854 rows=50000 loops=1)
 Total runtime: 36.226 ms
(2 rows)

                                                         QUERY PLAN             
                                            
----------------------------------------------------------------------------------------------------------------------------
 Index Scan using named_b_idx on b  (cost=0.41..4385.78 rows=51291 width=36) 
(actual time=0.036..27.166 rows=50000 loops=1)
 Total runtime: 29.418 ms
(2 rows)

                                                          QUERY PLAN            
                                              
------------------------------------------------------------------------------------------------------------------------------
 Sort  (cost=27371.05..27627.51 rows=102582 width=36) (actual 
time=435.566..535.213 rows=100000 loops=1)
   Sort Key: a.named
   Sort Method: external merge  Disk: 4576kB
   ->  Unique  (cost=14230.75..15000.12 rows=102582 width=36) (actual 
time=75.540..131.131 rows=100000 loops=1)
         ->  Sort  (cost=14230.75..14487.21 rows=102582 width=36) (actual 
time=75.539..102.016 rows=100000 loops=1)
               Sort Key: a.id, a.named
               Sort Method: external merge  Disk: 4584kB
               ->  Append  (cost=0.00..2885.64 rows=102582 width=36) (actual 
time=0.005..22.103 rows=100000 loops=1)
                     ->  Seq Scan on a  (cost=0.00..929.91 rows=51291 width=36) 
(actual time=0.005..6.389 rows=50000 loops=1)
                     ->  Seq Scan on b  (cost=0.00..929.91 rows=51291 width=36) 
(actual time=0.003..5.811 rows=50000 loops=1)
 Total runtime: 541.763 ms
(11 rows)

                                                          QUERY PLAN            
                                              
------------------------------------------------------------------------------------------------------------------------------
 Sort  (cost=26345.23..26601.69 rows=102582 width=36) (actual 
time=435.116..534.755 rows=100000 loops=1)
   Sort Key: a.named
   Sort Method: external merge  Disk: 4576kB
   ->  Unique  (cost=14230.75..15000.12 rows=102582 width=36) (actual 
time=75.025..130.706 rows=100000 loops=1)
         ->  Sort  (cost=14230.75..14487.21 rows=102582 width=36) (actual 
time=75.024..101.363 rows=100000 loops=1)
               Sort Key: a.id, a.named
               Sort Method: external merge  Disk: 4584kB
               ->  Append  (cost=0.00..2885.64 rows=102582 width=36) (actual 
time=0.006..21.939 rows=100000 loops=1)
                     ->  Seq Scan on a  (cost=0.00..929.91 rows=51291 width=36) 
(actual time=0.005..6.187 rows=50000 loops=1)
                     ->  Seq Scan on b  (cost=0.00..929.91 rows=51291 width=36) 
(actual time=0.004..5.890 rows=50000 loops=1)
 Total runtime: 541.167 ms
(11 rows)

                                                                  QUERY PLAN    
                                                              
----------------------------------------------------------------------------------------------------------------------------------------------
 Unique  (cost=21086.49..21855.86 rows=102582 width=36) (actual 
time=133.286..180.493 rows=100000 loops=1)
   ->  Sort  (cost=21086.49..21342.95 rows=102582 width=36) (actual 
time=133.285..157.196 rows=100000 loops=1)
         Sort Key: a.id, a.named
         Sort Method: external merge  Disk: 4568kB
         ->  Append  (cost=0.41..9741.38 rows=102582 width=36) (actual 
time=0.025..62.696 rows=100000 loops=1)
               ->  Index Scan using named_a_idx on a  (cost=0.41..4329.78 
rows=51291 width=36) (actual time=0.025..25.143 rows=50000 loops=1)
               ->  Index Scan using named_b_idx on b  (cost=0.41..4385.78 
rows=51291 width=36) (actual time=0.027..27.052 rows=50000 loops=1)
 Total runtime: 185.968 ms
(8 rows)

DROP VIEW
DROP TABLE
DROP TABLE
quentusrex=# 

create table a (
       id integer,
       named text);
create index named_a_idx on a (named);

create table b (
       id integer,
       named text);
create index named_b_idx on b (named);

insert into a (id, named) values (generate_series(1,100000,2), md5(random()::text));
insert into b (id, named) values (generate_series(2,100000,2), md5(random()::text));

create view testing as select * from a union select * from b;

explain analyze select * from a order by named;

explain analyze select * from b order by named;

explain analyze select * from testing order by named;

explain analyze (select id, named from a) union (select id, named from b) order by named;

explain analyze (select id, named from a order by named) union (select id, named from b order by named);

drop view testing;

drop table a;

drop table b;
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to