From 22481f3d89cf0204aeacde6f20d5b16bb5bc03ae Mon Sep 17 00:00:00 2001 From: Neill Magill Date: Thu, 22 Jun 2017 10:16:32 +0100 Subject: [PATCH] MDL-59317 message: Message page taking long time to load The OR clause in these queries used different sets of columns to select userid which meant that the indexes that included user id could not be used. This change splits the query so that each individual part can use one of the indexes that includes a userid which speeds them up considerably. --- message/classes/api.php | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/message/classes/api.php b/message/classes/api.php index b96006ec14f04..642353fdc4b1c 100644 --- a/message/classes/api.php +++ b/message/classes/api.php @@ -283,7 +283,14 @@ public static function get_conversations($userid, $limitfrom = 0, $limitnum = 20 FROM {message} WHERE (useridto = ? AND timeusertodeleted = 0 AND notification = 0) - OR + UNION ALL + SELECT + id, useridfrom, useridto, subject, fullmessage, fullmessageformat, + fullmessagehtml, smallmessage, notification, contexturl, + contexturlname, timecreated, timeuserfromdeleted, timeusertodeleted, + component, eventtype, 0 as timeread + FROM {message} + WHERE (useridfrom = ? AND timeuserfromdeleted = 0 AND notification = 0) UNION ALL SELECT @@ -294,7 +301,14 @@ public static function get_conversations($userid, $limitfrom = 0, $limitnum = 20 FROM {message_read} WHERE (useridto = ? AND timeusertodeleted = 0 AND notification = 0) - OR + UNION ALL + SELECT + id, useridfrom, useridto, subject, fullmessage, fullmessageformat, + fullmessagehtml, smallmessage, notification, contexturl, + contexturlname, timecreated, timeuserfromdeleted, timeusertodeleted, + component, eventtype, timeread + FROM {message_read} + WHERE (useridfrom = ? AND timeuserfromdeleted = 0 AND notification = 0)"; $allmessagesparams = [$userid, $userid, $userid, $userid]; @@ -350,7 +364,11 @@ public static function get_conversations($userid, $limitfrom = 0, $limitnum = 20 FROM {message} WHERE (useridto = ? AND timeusertodeleted = 0 AND notification = 0) - OR + AND timecreated $timecreatedsql + UNION ALL + SELECT id, useridfrom, useridto, timecreated + FROM {message} + WHERE (useridfrom = ? AND timeuserfromdeleted = 0 AND notification = 0) AND timecreated $timecreatedsql UNION ALL @@ -358,14 +376,19 @@ public static function get_conversations($userid, $limitfrom = 0, $limitnum = 20 FROM {message_read} WHERE (useridto = ? AND timeusertodeleted = 0 AND notification = 0) - OR + AND timecreated $timecreatedsql + UNION ALL + SELECT id, useridfrom, useridto, timecreated + FROM {message_read} + WHERE (useridfrom = ? AND timeuserfromdeleted = 0 AND notification = 0) AND timecreated $timecreatedsql"; $messageidsql = "SELECT $convosig, max(id) as id, timecreated FROM ($allmessagestimecreated) x WHERE $messageidwhere GROUP BY $convocase, timecreated"; - $messageidparams = array_merge([$userid, $userid], $timecreatedparams, [$userid, $userid], $timecreatedparams); + $messageidparams = array_merge([$userid], $timecreatedparams, [$userid], $timecreatedparams, + [$userid], $timecreatedparams, [$userid], $timecreatedparams); $messageidrecords = $DB->get_records_sql($messageidsql, $messageidparams); // Ok, let's recap. We've pulled a descending ordered list of conversations by latest time created