diff --git a/main/inc/lib/tracking.lib.php b/main/inc/lib/tracking.lib.php index 6f821c996b..25d4a53d53 100755 --- a/main/inc/lib/tracking.lib.php +++ b/main/inc/lib/tracking.lib.php @@ -1658,34 +1658,62 @@ class Tracking */ public static function get_course_connections_count($courseId, $session_id = 0, $start = 0, $stop = null) { - if ($start < 0) { + if ($start < 0) { $start = 0; } if (!isset($stop) or ($stop < 0)) { $stop = api_get_utc_datetime(); } - $start = Database::escape_string($start); - $stop = Database::escape_string($stop); + // Given we're storing in cache, round the start and end times + // to the lower minute + $roundedStart = substr($start, 0, -2) . '00'; + $roundedStop = substr($stop, 0, -2) . '00'; + $roundedStart = Database::escape_string($roundedStart); + $roundedStop = Database::escape_string($roundedStop); - $month_filter = " AND login_course_date > '$start' AND login_course_date < '$stop' "; + $month_filter = " AND login_course_date > '$roundedStart' AND login_course_date < '$roundedStop' "; $courseId = intval($courseId); $session_id = intval($session_id); $count = 0; - - $tbl_track_e_course_access = Database :: get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS); - $sql = "SELECT count(*) as count_connections + $tbl_track_e_course_access = Database :: get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS); + $sql = "SELECT count(*) as count_connections FROM $tbl_track_e_course_access WHERE c_id = $courseId AND session_id = $session_id $month_filter"; - $rs = Database::query($sql); - if (Database::num_rows($rs)>0) { - $row = Database::fetch_object($rs); - $count = $row->count_connections; - } + + //This query can be very slow (several seconds on an indexed table + // with 14M rows). As such, we'll try to use APCU if it is + // available to store the resulting value for a few seconds + $cacheEnabled = function_exists('apcu_exists'); + if ($cacheEnabled) { + $apc = apcu_cache_info(true); + $apc_end = $apc['start_time'] + $apc['ttl']; + + $apc_var = 'course_access_'.$courseId.'_'.$session_id.'_'.strtotime($roundedStart).'_'.strtotime($roundedStop); + if (apcu_exists($apc_var) && (time() < $apc_end) && + apcu_fetch($apc_var) > 0 + ) { + $count = apcu_fetch($apc_var); + } else { + $rs = Database::query($sql); + if (Database::num_rows($rs)>0) { + $row = Database::fetch_object($rs); + $count = $row->count_connections; + } + apcu_clear_cache(); + apcu_store($apc_var, $count, 60); + } + } else { + $rs = Database::query($sql); + if (Database::num_rows($rs)>0) { + $row = Database::fetch_object($rs); + $count = $row->count_connections; + } + } return $count; }