Please post the plan if we replace
 status IN ('0', '1')
with
 (status = '0' OR status = '1')
because that would allow us to keep our symbolic constants in the
source. I am also curious if this performs differently than IN because
it sure looks the exact same thing ;-)

Aaron

On Thu, 2006-10-05 at 09:27 -0400, [EMAIL PROTECTED] wrote:
> Greetings everyone!  I've been using DBMail for quite some time now and
> recently I've found myself interested in tweaking performance in
> PostgreSQL.  I've noticed that there's one particular query that keeps
> popping up that is notoriously slow and I believe I've found a tweak to
> increase the performance significantly.  Here's what I've seen:
> 
> Original query:
> SELECT seen_flag, answered_flag, deleted_flag, flagged_flag, draft_flag,
> recent_flag, TO_CHAR(internal_date, 'YYYY-MM-DD HH24:MI:SS' ), rfcsize,
> message_idnr FROM dbmail_messages msg, dbmail_physmessage pm WHERE pm.id =
> msg.physmessage_id AND message_idnr BETWEEN '1611115' AND '1611115' AND
> mailbox_idnr = '5' AND status IN ('0','1') ORDER BY message_idnr ASC;
> 
> PostgreSQL query plan and execution time:
>  Sort  (cost=906.07..906.08 rows=1 width=36) (actual time=79.336..79.338
> rows=1 loops=1)
>    Sort Key: msg.message_idnr
>    ->  Nested Loop  (cost=0.00..906.06 rows=1 width=36) (actual
> time=0.809..79.325 rows=1 loops=1)
>          ->  Index Scan using dbmail_messages_status_notdeleted_idx,
> dbmail_messages_status_notdeleted_idx on dbmail_messages msg
> (cost=0.00..900.04 rows=1 width=28) (actual time=0.721..79.230
> rows=1 loops=1)
>                Index Cond: ((status = 0::smallint) OR (status =
> 1::smallint))
>                Filter: ((message_idnr >= 1611115::bigint) AND
> (message_idnr <= 1611115::bigint) AND (mailbox_idnr =
> 5::bigint))
>          ->  Index Scan using dbmail_physmessage_pkey on
> dbmail_physmessage pm  (cost=0.00..6.01 rows=1 width=24) (actual
> time=0.055..0.057 rows=1 loops=1)
>                Index Cond: (pm.id = "outer".physmessage_id)
>  Total runtime: 79.426 ms
> 
> Possible new query:
> SELECT seen_flag, answered_flag, deleted_flag, flagged_flag, draft_flag,
> recent_flag, TO_CHAR(internal_date, 'YYYY-MM-DD HH24:MI:SS' ), rfcsize,
> message_idnr FROM dbmail_messages msg, dbmail_physmessage pm WHERE pm.id =
> msg.physmessage_id AND message_idnr BETWEEN '1611115' AND '1611115' AND
> mailbox_idnr = '5' AND status < 2 ORDER BY message_idnr ASC;
> 
> New PostgreSQL query plan and execution time:
>  Nested Loop  (cost=0.00..1216.39 rows=1 width=36) (actual
> time=0.128..0.138 rows=1 loops=1)
>    ->  Index Scan using messages_pkey on dbmail_messages msg
> (cost=0.00..1210.37 rows=1 width=28) (actual time=0.025..0.028 rows=1
> loops=1)
>          Index Cond: ((message_idnr >= 1611115::bigint) AND (message_idnr
> <= 1611115::bigint))
>          Filter: ((mailbox_idnr = 5::bigint) AND (status < 2))
>    ->  Index Scan using dbmail_physmessage_pkey on dbmail_physmessage pm
> (cost=0.00..6.01 rows=1 width=24) (actual time=0.056..0.060 rows=1 loops=1)
>          Index Cond: (pm.id = "outer".physmessage_id)
>  Total runtime: 0.203 ms
> (7 rows)
> 
> Forgive my ignorance since this is the first time I've looked at the code
> but I've simply replaced the "IN" clause with a "less than 2" clause.  I
> looked in my table and saw that the status flags in the dbmail-messages
> table were all either 0, 1, 2, or 5.  It looks like the status types in
> dbmailtypes.h will probably be pretty static and are defined as follows:
> 
> MESSAGE_STATUS_NEW     = 0
> MESSAGE_STATUS_SEEN    = 1
> MESSAGE_STATUS_DELETE  = 2
> MESSAGE_STATUS_PURGE   = 3
> MESSAGE_STATUS_UNUSED  = 4
> MESSAGE_STATUS_INSERT  = 5
> MESSAGE_STATUS_ERROR   = 6
> 
> So, my question is... is this the right place to suggest performance
> tweaks to SQL statements?  If not, where/to whom can I send this?
> 
> Thanks,
> Tim Mattison
> [EMAIL PROTECTED]
> 
> 
> 
> 
> _______________________________________________
> Dbmail-dev mailing list
> [email protected]
> http://twister.fastxs.net/mailman/listinfo/dbmail-dev

Reply via email to