Possible bug in planner (or planner not enough wise in some cases)

From: "Boguk Maxim" <astar(at)rambler-co(dot)ru>
To: <pgsql-admin(at)postgresql(dot)org>
Subject: Possible bug in planner (or planner not enough wise in some cases)
Date: 2006-09-18 13:35:52
Message-ID: E848E9BE34F3DA45BB56B5BEEC33204B1BC02D@prime.rambler.ramblermedia.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-admin

postgres version 8.1

all tables fresh vacuumed/analyzed

Problem table:

somedb=# \d el_comment
Table "public.el_comment"
Column | Type | Modifiers
------------------+-----------------------------+-----------------------------------------------------------------------
id | integer | not null default nextval(('public.documents_id_seq'::text)::regclass)
user_id | integer | not null
text_id | integer | not null
status | smallint | not null default 0
parent_id | integer |
Indexes:
"el_comment_pkey" PRIMARY KEY, btree (id)
"el_comment_parent_id" btree (parent_id)
"el_comment_text" btree (text_id)
"el_comment_user" btree (user_id)
Foreign-key constraints:
"delete_el_text" FOREIGN KEY (text_id) REFERENCES el_text(id) ON DELETE CASCADE

Problem query:

somedb=# EXPLAIN ANALYZE SELECT count(*) FROM el_comment WHERE ((parent_id IN (SELECT tt.id FROM el_comment as tt WHERE tt.user_id = 112 AND tt.status=1)) OR (text_id IN (SELECT el_text.id FROM el_text WHERE el_text.user_id = 112))) AND status=1;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------
Aggregate (cost=80641.51..80641.52 rows=1 width=0) (actual time=13528.870..13528.873 rows=1 loops=1)
-> Seq Scan on el_comment (cost=56.07..80352.97 rows=1154156 width=0) (actual time=113.866..13528.705 rows=15 loops=1)
Filter: ((status = 1) AND ((hashed subplan) OR (hashed subplan)))
SubPlan
-> Index Scan using el_text_user on el_text (cost=0.00..15.92 rows=12 width=4) (actual time=0.992..82.397 rows=12 loops=1)
Index Cond: (user_id = 112)
-> Index Scan using el_comment_user on el_comment tt (cost=0.00..40.14 rows=28 width=4) (actual time=8.748..21.661 rows=14 loops=1)
Index Cond: (user_id = 112)
Filter: (status = 1)
Total runtime: 13529.189 ms
(10 rows)

Now lets look output of both subqueries:
SELECT tt.id FROM el_comment as tt WHERE tt.user_id = 112 AND tt.status=1:

2766039
2766057
2244101
1929350
1929419
1929439
1490610
1052
2766033
2421000
2420878
611328
1019
1646
(14 rows)

and SELECT el_text.id FROM el_text WHERE el_text.user_id = 112

3758109
53688
1947631
1915372
1224421
1011606
13772
1017
463135
470614
575691
916229
(12 rows)

And put these values into query:

planet=# EXPLAIN ANALYZE SELECT count(*) FROM el_comment WHERE ((parent_id IN (2766039,2766057,2244101,1929350,1929419,1929439,1490610,1052,2766033,2421000,2420878,611328,1019,1646)) OR (text_id IN (3758109,53688,1947631,1915372,1224421,1011606,13772,1017,463135,470614,575691,916229))) AND status=1;

QUERY PLAN

Aggregate (cost=340.76..340.77 rows=1 width=0) (actual time=9.452..9.453 rows=1 loops=1)
-> Bitmap Heap Scan on el_comment (cost=52.24..340.71 rows=194 width=0) (actual time=5.431..9.269 rows=15 loops=1)
Recheck Cond: ((parent_id = 2766039) OR (parent_id = 2766057) OR (parent_id = 2244101) OR (parent_id = 1929350) OR (parent_id = 1929419) OR (parent_id = 1929439) OR (parent_id = 1490610) OR (parent_id = 1052) OR (parent_id = 2766033) OR (parent_id = 2421000) OR (parent_id = 2420878) OR (parent_id = 611328) OR (parent_id = 1019) OR (parent_id = 1646) OR (text_id = 3758109) OR (text_id = 53688) OR (text_id = 1947631) OR (text_id = 1915372) OR (text_id = 1224421) OR (text_id = 1011606) OR (text_id = 13772) OR (text_id = 1017) OR (text_id = 463135) OR (text_id = 470614) OR (text_id = 575691) OR (text_id = 916229))
Filter: (status = 1)
-> BitmapOr (cost=52.24..52.24 rows=194 width=0) (actual time=4.972..4.972 rows=0 loops=1)
-> Bitmap Index Scan on el_comment_parent_id (cost=0.00..2.00 rows=2 width=0) (actual time=0.582..0.582 rows=
1 loops=1)
Index Cond: (parent_id = 2766039)
....
14 same rows
....

-> Bitmap Index Scan on el_comment_text (cost=0.00..2.02 rows=13 width=0) (actual time=0.983..0.983 rows=0 loops=1)
Index Cond: (text_id = 3758109)
....
11 same rows
....

Total runtime: 10.368 ms
(58 rows)

Complete different result (1000x times faster). Issue look like planner can't/dont want try count both subquery's results and use bitmap scan.
And planner see amount of results from both subqueris small so bitmap scan must be look way better.
That is intended or bug?

PS: i got reasonable fast results via rewrite query as
select count(*) from
(
select t1.id from el_comment as t1 join el_comment as t2 on t1.parent_id=t2.id and t2.user_id=112 and t2.status=1 where t1.status=1
union
select t1.id from el_comment as t1 join el_text as t2 on t1.text_id=t2.id and t2.user_id=112 and t2.status=1
) as qqq;

but that is just workaround and work 2-5x time slower.

SY Maxim Boguk

Responses

Browse pgsql-admin by date

  From Date Subject
Next Message Magnus Hagander 2006-09-18 14:10:02 Re: Instructions For Building On Windows?
Previous Message Shoaib Mir 2006-09-18 13:31:41 Re: Instructions For Building On Windows?