inheritance, and plans

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hey folks,

I have few tables, that inherit from table X.
The query I perform, tries to obtain information about changes in all
tables that inherit from X,
aside from that, I have table Y that keeps another information related
to changes, but in bit different schema.
Anyway, there is one unique id field, shared amongst them.

When I want to obtain all that information, I do:


select updateid from (
  select updateid from r.skel
union all
  select updateid from r.history
) as foo
  where  updateid > 1232634919168805;

And what amazes me, is that no matter what value I choose in where X >
, postgres will always think this is the best plan:

                                              QUERY PLAN
-------------------------------------------------------------------------------------------------------
 Subquery Scan foo  (cost=0.00..167736.75 rows=978726 width=8)
   Filter: (foo.updateid > 1232634919168805::bigint)
   ->  Append  (cost=0.00..131034.54 rows=2936177 width=8)
         ->  Subquery Scan "*SELECT* 1"  (cost=0.00..130999.94
rows=2934947 width=8)
               ->  Result  (cost=0.00..101650.47 rows=2934947 width=8)
                     ->  Append  (cost=0.00..101650.47 rows=2934947 width=8)
                           ->  Seq Scan on skel  (cost=0.00..24.80
rows=1480 width=8)
                           ->  Seq Scan on a skel
(cost=0.00..22028.96 rows=923596 width=8)
                           ->  Seq Scan on b skel  (cost=0.00..8.01
rows=201 width=8)
                           ->  Seq Scan on c skel  (cost=0.00..1.81
rows=81 width=8)
                           ->  Seq Scan on d skel
(cost=0.00..22117.94 rows=923594 width=8)
                           ->  Seq Scan on e skel  (cost=0.00..6.03
rows=303 width=8)
                           ->  Seq Scan on f skel  (cost=0.00..6.02
rows=202 width=8)
                           ->  Seq Scan on g skel  (cost=0.00..1987.40
rows=85140 width=8)
                           ->  Seq Scan on h skel  (cost=0.00..1.01
rows=1 width=8)
                           ->  Seq Scan on i skel
(cost=0.00..55454.99 rows=999999 width=8)
                           ->  Seq Scan on j skel  (cost=0.00..13.50
rows=350 width=8)
         ->  Seq Scan on history  (cost=0.00..22.30 rows=1230 width=8)
(18 rows)

so my question is, why isn't postgres use index on some tables , and
search for the X > N individually ?

Because, yet - I tried to recreate problem, but I wasn't able. I have
this test db:

create schema r;

create sequence fooseq;
create domain r.fooint AS bigint NOT NULL default  nextval('fooseq');

create table skel(aid r.fooint, cd timestamp default now() not null);

create table one( a bigserial, aid r.fooint, cd timestamp not null);
create table two( a bigserial, aid r.fooint, cd timestamp not null);
create table three( a bigserial, aid r.fooint, cd timestamp not null);
create table four( a bigserial, aid r.fooint, cd timestamp not null);
create table five( a bigserial, aid r.fooint, cd timestamp not null);

create unique index one_aid on one(aid);
create unique index two_aid on two(aid);
create unique index three_aid on three(aid);
create unique index four_aid on four(aid);
create unique index five_aid on five(aid);


create table numbers( something int default random()*666, aid_foo r.fooint);

create unique index numbers_aid on numbers(aid_foo);

insert into one(a, cd) select generate_series(1,2000000), now();
insert into two(a, cd) select generate_series(1,200000), now();
insert into three(a, cd) select generate_series(1,2200000), now();
insert into four(a, cd) select generate_series(1,2200000), now();
insert into five(a, cd) select generate_series(1,2200000), now();

insert into numbers(something) select generate_series(1,870000);

alter table one inherit skel;
alter table two inherit skel;
alter table three inherit skel;
alter table four inherit skel;
alter table five inherit skel;


But no matter how many tables I throw in ( and I got to 20 ) - it will
always do it right:
gjaskie=# explain  select aid from (select aid from skel union all
select aid_foo as aid from numbers) AS foo where  aid > 999000;
                                         QUERY PLAN
---------------------------------------------------------------------------------------------
 Result  (cost=0.00..178034.88 rows=8661268 width=8)
   ->  Append  (cost=0.00..178034.88 rows=8661268 width=8)
         ->  Seq Scan on skel  (cost=0.00..32.12 rows=590 width=8)
               Filter: ((aid)::bigint > 999000)
         ->  Index Scan using one_aid on one skel
(cost=0.00..34549.76 rows=991445 width=8)
               Index Cond: ((aid)::bigint > 999000)
         ->  Seq Scan on two skel  (cost=0.00..3774.00 rows=199980 width=8)
               Filter: ((aid)::bigint > 999000)
         ->  Seq Scan on three skel  (cost=0.00..41513.00 rows=2199780 width=8)
               Filter: ((aid)::bigint > 999000)
         ->  Seq Scan on four skel  (cost=0.00..41513.00 rows=2199780 width=8)
               Filter: ((aid)::bigint > 999000)
         ->  Seq Scan on five skel  (cost=0.00..41513.00 rows=2199780 width=8)
               Filter: ((aid)::bigint > 999000)
         ->  Seq Scan on numbers  (cost=0.00..15140.00 rows=869913 width=8)
               Filter: ((aid_foo)::bigint > 999000)
(16 rows)

Time: 36.326 ms



But, if I add another union, it screws it up:

gjaskie=# explain  select aid from (select aid from skel union all
select aid_foo as aid from numbers union all select 1 aid) AS foo
where  aid > 999000;
                                               QUERY PLAN
--------------------------------------------------------------------------------------------------------
 Subquery Scan foo  (cost=0.00..374659.56 rows=3223924 width=8)
   Filter: (foo.aid > 999000)
   ->  Append  (cost=0.00..253762.42 rows=9671771 width=8)
         ->  Result  (cost=0.00..253762.40 rows=9671770 width=8)
               ->  Append  (cost=0.00..253762.40 rows=9671770 width=8)
                     ->  Result  (cost=0.00..144079.70 rows=8801770 width=8)
                           ->  Append  (cost=0.00..144079.70
rows=8801770 width=8)
                                 ->  Seq Scan on skel
(cost=0.00..27.70 rows=1770 width=8)
                                 ->  Seq Scan on one skel
(cost=0.00..32739.00 rows=2000000 width=8)
                                 ->  Seq Scan on two skel
(cost=0.00..3274.00 rows=200000 width=8)
                                 ->  Seq Scan on three skel
(cost=0.00..36013.00 rows=2200000 width=8)
                                 ->  Seq Scan on four skel
(cost=0.00..36013.00 rows=2200000 width=8)
                                 ->  Seq Scan on five skel
(cost=0.00..36013.00 rows=2200000 width=8)
                     ->  Seq Scan on numbers  (cost=0.00..12965.00
rows=870000 width=8)
         ->  Subquery Scan "*SELECT* 3"  (cost=0.00..0.02 rows=1 width=0)
               ->  Result  (cost=0.00..0.01 rows=1 width=0)
(16 rows)

Time: 1.502 ms

now the question is, how my test db's query:
  select aid from (select aid from skel union all select aid_foo as
aid from numbers union all select 1 aid) AS foo where  aid > 999000;

differ from original:
  select updateid from ( select updateid from r.skel union all select
updateid from r.history ) as foo where  updateid > 1232634919168805;


Oh, and the value N doesn't change the plan here either :/

tested on both 8.3 and 8.4, same results..
ideas welcomed

-- 
GJ

-- 
Sent via pgsql-performance mailing list (pgsql-performance@xxxxxxxxxxxxxx)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance

[Postgresql General]     [Postgresql PHP]     [PHP Users]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Books]     [PHP Databases]     [Yosemite]

  Powered by Linux