Paul J Stevens wrote:
> Brian Neu wrote:
>> It's the "BETWEEN" construct, or what it does rather.
>>
>> "AND message_idnr >= 253775 AND message_idnr <= 253775"  did the same thing.
>>
>> "message_idnr = 253775" brought a 70ms query, instead of 7+ seconds.
>>
>> Sooo . . . . . . . ummmm.  What would people that are smarter than me in 
>> this arena suggest that I do about this?  Obviously someone chose a range 
>> for a reason.
> 
> I'll fix this before 2.2.6

Brian,

I've fixed this in dbmail_2_2_branch.

I'm attaching the patch so you can apply it yourself.


-- 
  ________________________________________________________________
  Paul Stevens                                      paul at nfg.nl
  NET FACILITIES GROUP                     GPG/PGP: 1024D/11F8CD31
  The Netherlands________________________________http://www.nfg.nl
>From 05756a49505611fdcbc9a8b127aef6baae4bcaf6 Mon Sep 17 00:00:00 2001
From: Paul J Stevens <[EMAIL PROTECTED]>
Date: Thu, 21 Jun 2007 10:14:20 +0200
Subject: collapse BETWEEN clause if hi and low values are equal

---
 dbmail-imapsession.c |   37 +++++++++++++++++++++++++++++--------
 1 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/dbmail-imapsession.c b/dbmail-imapsession.c
index b72273c..578dc72 100644
--- a/dbmail-imapsession.c
+++ b/dbmail-imapsession.c
@@ -32,6 +32,7 @@
 #define SEND_BUF_SIZE 1024
 #define MAX_ARGS 512
 #define IDLE_TIMEOUT 30
+#define RANGE_SIZE 128
 
 extern db_param_t _db_params;
 #define DBPFX _db_params.pfx
@@ -700,6 +701,7 @@ int dbmail_imap_session_fetch_parse_args(struct ImapSession * self)
 	return 1; //theres more...
 }
 
+
 GTree * dbmail_imap_session_get_msginfo(struct ImapSession *self, GTree *ids)
 {
 
@@ -711,8 +713,9 @@ GTree * dbmail_imap_session_get_msginfo(struct ImapSession *self, GTree *ids)
 	GList *l, *t;
 	u64_t *uid, *lo, *hi;
 	u64_t id;
-	char query[DEF_QUERYSIZE];
+	char query[DEF_QUERYSIZE], range[RANGE_SIZE];
 	memset(query,0,DEF_QUERYSIZE);
+	memset(range,0,RANGE_SIZE);
 	
 	if (! (ids && g_tree_nnodes(ids)>0))
 		return NULL;
@@ -734,15 +737,20 @@ GTree * dbmail_imap_session_get_msginfo(struct ImapSession *self, GTree *ids)
 		
 	db_free_result();
 
+	if (*lo == *hi) 
+		snprintf(range,RANGE_SIZE,"= %llu", *lo);
+	else
+		snprintf(range,RANGE_SIZE,"BETWEEN %llu AND %llu", *lo, *hi);
+
 	snprintf(query, DEF_QUERYSIZE,
 		 "SELECT seen_flag, answered_flag, deleted_flag, flagged_flag, "
 		 "draft_flag, recent_flag, %s, rfcsize, message_idnr "
 		 "FROM %smessages msg, %sphysmessage pm "
 		 "WHERE pm.id = msg.physmessage_id "
-		 "AND message_idnr BETWEEN %llu AND %llu "
+		 "AND message_idnr %s "
 		 "AND mailbox_idnr = %llu AND status IN (%d,%d,%d) "
 		 "ORDER BY message_idnr ASC",to_char_str,DBPFX,DBPFX,
-		 *lo, *hi, ud->mailbox.uid,
+		 range, ud->mailbox.uid,
 		 MESSAGE_STATUS_NEW, MESSAGE_STATUS_SEEN,MESSAGE_STATUS_DELETE);
 	g_free(to_char_str);
 
@@ -1043,7 +1051,9 @@ static void _fetch_envelopes(struct ImapSession *self)
 	u64_t id;
 	static int lo = 0;
 	static u64_t hi = 0;
+	char range[RANGE_SIZE];
 	GList *last;
+	memset(range,0,RANGE_SIZE);
 
 	if (! self->envelopes) {
 		self->envelopes = g_tree_new_full((GCompareDataFunc)ucmp,NULL,(GDestroyNotify)g_free,(GDestroyNotify)g_free);
@@ -1062,13 +1072,18 @@ static void _fetch_envelopes(struct ImapSession *self)
 		last = g_list_last(self->ids_list);
 	hi = *(u64_t *)last->data;
 
+	if (self->msg_idnr == hi)
+		snprintf(range,RANGE_SIZE,"= %llu", self->msg_idnr);
+	else
+		snprintf(range,RANGE_SIZE,"BETWEEN %llu AND %llu", self->msg_idnr, hi);
+
 	g_string_printf(q,"SELECT message_idnr,envelope "
 			"FROM %senvelope e "
 			"JOIN %smessages m ON m.physmessage_id=e.physmessage_id "
 			"WHERE m.mailbox_idnr = %llu "
-			"AND message_idnr BETWEEN %llu AND %llu ",
+			"AND message_idnr %s",
 			DBPFX, DBPFX,  
-			self->mailbox->id, self->msg_idnr, hi);
+			self->mailbox->id, range);
 	
 	if (db_query(q->str)==-1)
 		return;
@@ -1151,6 +1166,8 @@ static void _fetch_headers(struct ImapSession *self, body_fetch_t *bodyfetch, gb
 	static int lo = 0;
 	static u64_t hi = 0;
 	static u64_t ceiling = 0;
+	char range[RANGE_SIZE];
+	memset(range,0,RANGE_SIZE);
 
 	if (! self->headers) {
 		TRACE(TRACE_DEBUG, "init self->headers");
@@ -1196,16 +1213,20 @@ static void _fetch_headers(struct ImapSession *self, body_fetch_t *bodyfetch, gb
 		last = g_list_last(self->ids_list);
 	hi = *(u64_t *)last->data;
 
+	if (self->msg_idnr == hi)
+		snprintf(range,RANGE_SIZE,"= %llu", self->msg_idnr);
+	else
+		snprintf(range,RANGE_SIZE,"BETWEEN %llu AND %llu", self->msg_idnr, hi);
+
 	g_string_printf(q,"SELECT message_idnr,headername,headervalue "
 			"FROM %sheadervalue v "
 			"JOIN %smessages m ON v.physmessage_id=m.physmessage_id "
 			"JOIN %sheadername n ON v.headername_id=n.id "
 			"WHERE m.mailbox_idnr = %llu "
-			"AND message_idnr BETWEEN %llu AND %llu "
+			"AND message_idnr %s "
 			"AND lower(headername) %s IN ('%s')",
 			DBPFX, DBPFX, DBPFX,
-			self->mailbox->id,
-			self->msg_idnr, hi, 
+			self->mailbox->id, range, 
 			not?"NOT":"", bodyfetch->hdrnames);
 	
 	if (db_query(q->str)==-1)
-- 
1.5.1

_______________________________________________
DBmail mailing list
[email protected]
https://mailman.fastxs.nl/mailman/listinfo/dbmail

Reply via email to