From c08ea5202f27ca2dc8d99cbd17b83fc58ba376ee Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Wed, 4 Apr 2012 13:57:27 +0100 Subject: [PATCH] MDL-32462 accesslib: fix context_user::build_paths performance The problem was that the query was updating every row whether it needed it or not. This turns out to be a really bad thing to do on Postgres, because it then triggers a long expensive vacuum, which lock the context table for a long time a really bad thing to do. --- lib/accesslib.php | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/lib/accesslib.php b/lib/accesslib.php index 81c5bca9cc8..605bb00cb97 100644 --- a/lib/accesslib.php +++ b/lib/accesslib.php @@ -5853,12 +5853,24 @@ class context_user extends context { protected static function build_paths($force) { global $DB; - // first update normal users + // First update normal users. + $path = $DB->sql_concat('?', 'id'); + $pathstart = '/' . SYSCONTEXTID . '/'; + $params = array($pathstart); + + if ($force) { + $where = "depth <> 2 OR path IS NULL OR path <> ({$path})"; + $params[] = $pathstart; + } else { + $where = "depth = 0 OR path IS NULL"; + } + $sql = "UPDATE {context} SET depth = 2, - path = ".$DB->sql_concat("'/".SYSCONTEXTID."/'", 'id')." - WHERE contextlevel=".CONTEXT_USER; - $DB->execute($sql); + path = {$path} + WHERE contextlevel = " . CONTEXT_USER . " + AND ($where)"; + $DB->execute($sql, $params); } }