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 b96006ec14f..642353fdc4b 100644 --- a/message/classes/api.php +++ b/message/classes/api.php @@ -283,7 +283,14 @@ class api { 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 @@ class api { 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 @@ class api { 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 @@ class api { 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