Hi,

I get more and more user complaints that my IMAP server is terrible
slow, opening a mailbox takes very long.

I've analyzed that using PQA (http://pgfoundry.org/projects/pqa/, great
tool!), the output is attached if anyone is interested (includes all
databases, not only dbmail).

The main problem is in db.c, db_getmailbox():
SELECT COUNT(message_idnr), COUNT(message_idnr) - SUM(seen_flag),
SUM(recent_flag) FROM dbmail_messages WHERE mailbox_idnr = '5' AND
status < '2'
That query takes up to 15 seconds (!!).

Obviously that doesn't scale at all - dbmail is not usable on PostgreSQL
with lot of mails and/or users.

If I replace COUNT(message_idnr) with the value I get the query is about
30 (!) times faster and takes about 0.4 seconds:

SELECT 611, 611 - SUM(seen_flag), SUM(recent_flag) FROM dbmail_messages
WHERE mailbox_idnr = '5' AND status < '2';

So the solution is easy: add a row to dbmail_mailboxes that contains the
number of messages. The row is updated by a trigger when messages are
inserted or deleted. That is a quick and easy fix (only one query in the
dbmail code has to be changed) - but that doesn't work for MySQL, I know :-/

I think in this case database abstraction simply doesn't work. We have
to use two different queries in the code, but I might be wrong. Does
anyone have a better solution?


Thomas
-- 
http://www.tmueller.com for pgp key (95702B3B)
Title: SQL Query Analysis (generated Wed Mar 09 09:14:24 CET 2005)

SQL Query Analysis (generated Wed Mar 09 09:14:24 CET 2005)



Reports
Overall statistics
Queries by type
Queries that took up the most time
Slowest queries
Most frequent queries

Overall statistics

375375 queries
262 unique queries
Total query duration was 7389.75 seconds
Longest query (SELECT pnd."SeqId",pnd."TableName", pnd."Op",pnddata."IsKey", pnddata."Data" AS "Data" FROM "Pending" pnd, "PendingData" pnddata WHERE pnd."SeqId" = pnddata."SeqId" AND pnd."XID"={ } ORDER BY "SeqId", "IsKey" DESC) ran in 84.216 seconds
Shortest query (SET DATESTYLE = ISO) ran in 0.000 seconds
Log file parsed in 358.1 seconds

Queries by type

TypeCountPercentage
SELECT30603582
INSERT4653112
UPDATE100283
DELETE104153

Queries that took up the most time

RankTotal time (seconds)Times executedQuery text
12532.2489593SELECT COUNT(message_idnr), COUNT(message_idnr) - SUM(seen_flag), SUM(recent_flag) FROM dbmail_messages WHERE mailbox_idnr = { } AND status < { }
21398.0389526SELECT message_idnr FROM dbmail_messages WHERE mailbox_idnr = { } AND status < { } ORDER BY message_idnr ASC
3515.2949933INSERT INTO "PendingData" ("SeqId","IsKey","Data") VALUES(currval({ }),{ },$1)
4340.67332SELECT filename,md5sum,size,mtime FROM filelist WHERE owner={ } AND filename LIKE { } EXCEPT SELECT filename,md5sum,size,mtime FROM filelist WHERE owner={ } AND filename LIKE { } ORDER BY filename ASC LIMIT { } OFFSET { }
5312.4323375select a.oid,a.relname,a.relnamespace,a.relpages,a.relisshared,a.reltuples,b.schemaname,b.n_tup_ins,b.n_tup_upd,b.n_tup_del from pg_class a, pg_stat_all_tables b where a.oid=b.relid and a.relkind = { } and schemaname not like { }
6302.9861815SELECT seen_flag, answered_flag, deleted_flag, flagged_flag, draft_flag, recent_flag, TO_CHAR(internal_date, { } ), rfcsize, message_idnr FROM dbmail_messages msg, dbmail_physmessage pm WHERE pm.id = msg.physmessage_id AND message_idnr BETWEEN { } AND { } AND mailbox_idnr = { } AND status < { } ORDER BY message_idnr ASC
7209.4898932INSERT INTO "MirroredTransaction" ("XID","LastSeqId","MirrorHostId") VALUES ({ },{ },{ })
8202.15241707SELECT messageblk FROM dbmail_messageblks blk, dbmail_messages msg WHERE blk.physmessage_id = msg.physmessage_id AND msg.message_idnr = { } ORDER BY blk.messageblk_idnr ASC LIMIT { }
9198.8438932DELETE FROM "Pending" WHERE "XID"={ } AND (SELECT COUNT(*) FROM "MirroredTransaction" WHERE "XID"={ })=(SELECT COUNT(*) FROM "MirrorHost")
10196.4298988SELECT pnd."SeqId",pnd."TableName", pnd."Op",pnddata."IsKey", pnddata."Data" AS "Data" FROM "Pending" pnd, "PendingData" pnddata WHERE pnd."SeqId" = pnddata."SeqId" AND pnd."XID"={ } ORDER BY "SeqId", "IsKey" DESC
11111.9629068SELECT DISTINCT name FROM tmm_customer_domains WHERE name={ }
1273.8093837SELECT MIN(message_idnr) FROM dbmail_messages WHERE mailbox_idnr = { } AND status < { } AND seen_flag = { }
1370.2201884commit
1465.3255948SELECT block.messageblk FROM dbmail_messageblks block, dbmail_messages msg WHERE block.physmessage_id = msg.physmessage_id AND msg.message_idnr = { } ORDER BY block.messageblk_idnr
1560.51145277select content,ttl,prio,type,domain_id,name from records where type={ } and name={ }

Slowest queries

RankTimeQuery text
184.216SELECT pnd."SeqId",pnd."TableName", pnd."Op",pnddata."IsKey", pnddata."Data" AS "Data" FROM "Pending" pnd, "PendingData" pnddata WHERE pnd."SeqId" = pnddata."SeqId" AND pnd."XID"={ } ORDER BY "SeqId", "IsKey" DESC
281.209SELECT pnd."SeqId",pnd."TableName", pnd."Op",pnddata."IsKey", pnddata."Data" AS "Data" FROM "Pending" pnd, "PendingData" pnddata WHERE pnd."SeqId" = pnddata."SeqId" AND pnd."XID"={ } ORDER BY "SeqId", "IsKey" DESC
357.863SELECT seen_flag, answered_flag, deleted_flag, flagged_flag, draft_flag, recent_flag, TO_CHAR(internal_date, { } ), rfcsize, message_idnr FROM dbmail_messages msg, dbmail_physmessage pm WHERE pm.id = msg.physmessage_id AND message_idnr BETWEEN { } AND { } AND mailbox_idnr = { } AND status < { } ORDER BY message_idnr ASC
445.004SELECT seen_flag, answered_flag, deleted_flag, flagged_flag, draft_flag, recent_flag, TO_CHAR(internal_date, { } ), rfcsize, message_idnr FROM dbmail_messages msg, dbmail_physmessage pm WHERE pm.id = msg.physmessage_id AND message_idnr BETWEEN { } AND { } AND mailbox_idnr = { } AND status < { } ORDER BY message_idnr ASC
537.403SELECT seen_flag, answered_flag, deleted_flag, flagged_flag, draft_flag, recent_flag, TO_CHAR(internal_date, { } ), rfcsize, message_idnr FROM dbmail_messages msg, dbmail_physmessage pm WHERE pm.id = msg.physmessage_id AND message_idnr BETWEEN { } AND { } AND mailbox_idnr = { } AND status < { } ORDER BY message_idnr ASC
632.138SELECT seen_flag, answered_flag, deleted_flag, flagged_flag, draft_flag, recent_flag, TO_CHAR(internal_date, { } ), rfcsize, message_idnr FROM dbmail_messages msg, dbmail_physmessage pm WHERE pm.id = msg.physmessage_id AND message_idnr BETWEEN { } AND { } AND mailbox_idnr = { } AND status < { } ORDER BY message_idnr ASC
729.513SELECT seen_flag, answered_flag, deleted_flag, flagged_flag, draft_flag, recent_flag, TO_CHAR(internal_date, { } ), rfcsize, message_idnr FROM dbmail_messages msg, dbmail_physmessage pm WHERE pm.id = msg.physmessage_id AND message_idnr BETWEEN { } AND { } AND mailbox_idnr = { } AND status < { } ORDER BY message_idnr ASC
828.300SELECT seen_flag, answered_flag, deleted_flag, flagged_flag, draft_flag, recent_flag, TO_CHAR(internal_date, { } ), rfcsize, message_idnr FROM dbmail_messages msg, dbmail_physmessage pm WHERE pm.id = msg.physmessage_id AND message_idnr BETWEEN { } AND { } AND mailbox_idnr = { } AND status < { } ORDER BY message_idnr ASC
920.188SELECT usr.user_idnr, sum(pm.messagesize), usr.curmail_size FROM dbmail_users usr LEFT JOIN dbmail_mailboxes mbx ON mbx.owner_idnr = usr.user_idnr LEFT JOIN dbmail_messages msg ON msg.mailbox_idnr = mbx.mailbox_idnr LEFT JOIN dbmail_physmessage pm ON pm.id = msg.physmessage_id AND msg.status < { } GROUP BY usr.user_idnr, usr.curmail_size HAVING ((SUM(pm.messagesize) <> usr.curmail_size) OR (NOT (SUM(pm.messagesize) IS NOT NULL) AND usr.curmail_size <> { }))
1019.975DELETE FROM net_packets_raw WHERE timestamp < { }
1117.378SELECT filename,md5sum,size,mtime FROM filelist WHERE owner={ } AND filename LIKE { } EXCEPT SELECT filename,md5sum,size,mtime FROM filelist WHERE owner={ } AND filename LIKE { } ORDER BY filename ASC LIMIT { } OFFSET { }
1215.587SELECT COUNT(message_idnr), COUNT(message_idnr) - SUM(seen_flag), SUM(recent_flag) FROM dbmail_messages WHERE mailbox_idnr = { } AND status < { }
1315.554SELECT message_idnr FROM dbmail_messages WHERE mailbox_idnr = { } AND status < { } ORDER BY message_idnr ASC
1415.186SELECT filename,md5sum,size,mtime FROM filelist WHERE owner={ } AND filename LIKE { } EXCEPT SELECT filename,md5sum,size,mtime FROM filelist WHERE owner={ } AND filename LIKE { } ORDER BY filename ASC LIMIT { } OFFSET { }
1514.212SELECT filename,md5sum,size,mtime FROM filelist WHERE owner={ } AND filename LIKE { } EXCEPT SELECT filename,md5sum,size,mtime FROM filelist WHERE owner={ } AND filename LIKE { } ORDER BY filename ASC LIMIT { } OFFSET { }

Most frequent queries

RankTimes executedQuery text
145277select content,ttl,prio,type,domain_id,name from records where type={ } and name={ }
241707SELECT messageblk FROM dbmail_messageblks blk, dbmail_messages msg WHERE blk.physmessage_id = msg.physmessage_id AND msg.message_idnr = { } ORDER BY blk.messageblk_idnr ASC LIMIT { }
322776SELECT no_select FROM dbmail_mailboxes WHERE mailbox_idnr = { }
420731INSERT INTO "PendingData" ("SeqId","IsKey","Data") VALUES(currval({ }),{ },$1)
519014SELECT owner_idnr FROM dbmail_mailboxes WHERE mailbox_idnr = { }
618917SELECT no_inferiors FROM dbmail_mailboxes WHERE mailbox_idnr = { }
718917SELECT name FROM dbmail_mailboxes WHERE mailbox_idnr = { }
816366SELECT mailbox_idnr FROM dbmail_mailboxes WHERE mailbox_idnr = { } AND owner_idnr = { }
912984INSERT INTO "Pending" ("TableName","Op","XID") VALUES ($1,$2,$3)
109593SELECT COUNT(message_idnr), COUNT(message_idnr) - SUM(seen_flag), SUM(recent_flag) FROM dbmail_messages WHERE mailbox_idnr = { } AND status < { }
119593SELECT message_idnr + { } FROM dbmail_messages ORDER BY message_idnr DESC LIMIT { }
129593SELECT permission,seen_flag,answered_flag,deleted_flag,flagged_flag,recent_flag,draft_flag FROM dbmail_mailboxes WHERE mailbox_idnr = { }
139526SELECT message_idnr FROM dbmail_messages WHERE mailbox_idnr = { } AND status < { } ORDER BY message_idnr ASC
149154SELECT indkey FROM pg_index WHERE indisprimary={ } AND indrelid={ }
159068SELECT DISTINCT name FROM tmm_customer_domains WHERE name={ }

Reply via email to