CRM-18096 Slow queries when rendering logging tab
authoreileen <emcnaughton@wikimedia.org>
Tue, 23 Feb 2016 23:01:08 +0000 (12:01 +1300)
committereileen <emcnaughton@wikimedia.org>
Mon, 7 Mar 2016 22:23:21 +0000 (11:23 +1300)
CRM/Logging/ReportSummary.php
CRM/Report/Form/Contact/LoggingSummary.php

index 45c8759cc36abddd6f84b1eaa0f2b15739b85c4e..c40d908865d4cb4ae227ef7b8296207a7e321aaf 100644 (file)
@@ -38,6 +38,13 @@ class CRM_Logging_ReportSummary extends CRM_Report_Form {
 
   protected $loggingDB;
 
+  /**
+   * The log table currently being processed.
+   *
+   * @var string
+   */
+  protected $currentLogTable;
+
   /**
    * Class constructor.
    */
@@ -49,12 +56,7 @@ class CRM_Logging_ReportSummary extends CRM_Report_Form {
     $this->loggingDB = $dsn['database'];
 
     // used for redirect back to contact summary
-    $this->cid = CRM_Utils_Request::retrieve('cid', 'Integer', CRM_Core_DAO::$_nullObject);
-
-    $activityContacts = CRM_Core_OptionGroup::values('activity_contacts', FALSE, FALSE, FALSE, NULL, 'name');
-    $sourceID = CRM_Utils_Array::key('Activity Source', $activityContacts);
-    $assigneeID = CRM_Utils_Array::key('Activity Assignees', $activityContacts);
-    $targetID = CRM_Utils_Array::key('Activity Targets', $activityContacts);
+    $this->cid = CRM_Utils_Request::retrieve('cid', 'Integer');
 
     $this->_logTables = array(
       'log_civicrm_contact' => array(
@@ -120,44 +122,17 @@ class CRM_Logging_ReportSummary extends CRM_Report_Form {
           'column' => 'label_a_b',
         ),
       ),
-      'log_civicrm_activity_for_target' => array(
-        'fk' => 'contact_id',
-        'table_name' => 'log_civicrm_activity',
-        'joins' => array(
-          'table' => 'log_civicrm_activity_contact',
-          'join' => "(entity_log_civireport.id = fk_table.activity_id AND fk_table.record_type_id = {$targetID})",
-        ),
-        'bracket_info' => array(
-          'entity_column' => 'activity_type_id',
-          'options' => CRM_Core_PseudoConstant::activityType(TRUE, TRUE, FALSE, 'label', TRUE),
-        ),
-        'log_type' => 'Activity',
-      ),
-      'log_civicrm_activity_for_assignee' => array(
+      'log_civicrm_activity_contact' => array(
         'fk' => 'contact_id',
-        'table_name' => 'log_civicrm_activity',
-        'joins' => array(
-          'table' => 'log_civicrm_activity_contact',
-          'join' => "entity_log_civireport.id = fk_table.activity_id AND fk_table.record_type_id = {$assigneeID}",
-        ),
-        'bracket_info' => array(
-          'entity_column' => 'activity_type_id',
-          'options' => CRM_Core_PseudoConstant::activityType(TRUE, TRUE, FALSE, 'label', TRUE),
-        ),
+        'table_name' => 'log_civicrm_activity_contact',
         'log_type' => 'Activity',
-      ),
-      'log_civicrm_activity_for_source' => array(
-        'fk' => 'contact_id',
-        'table_name' => 'log_civicrm_activity',
-        'joins' => array(
-          'table' => 'log_civicrm_activity_contact',
-          'join' => "entity_log_civireport.id = fk_table.activity_id AND fk_table.record_type_id = {$sourceID}",
-        ),
+        'field' => 'activity_id',
+
         'bracket_info' => array(
           'entity_column' => 'activity_type_id',
           'options' => CRM_Core_PseudoConstant::activityType(TRUE, TRUE, FALSE, 'label', TRUE),
+          'lookup_table' => 'log_civicrm_activity',
         ),
-        'log_type' => 'Activity',
       ),
       'log_civicrm_case' => array(
         'fk' => 'contact_id',
@@ -208,24 +183,25 @@ class CRM_Logging_ReportSummary extends CRM_Report_Form {
     $this->_groupBy = 'GROUP BY entity_log_civireport.log_conn_id, entity_log_civireport.log_user_id, EXTRACT(DAY_MICROSECOND FROM entity_log_civireport.log_date), entity_log_civireport.id';
   }
 
-  public function select() {
-    $select = array();
-    $this->_columnHeaders = array();
-    foreach ($this->_columns as $tableName => $table) {
-      if (array_key_exists('fields', $table)) {
-        foreach ($table['fields'] as $fieldName => $field) {
-          if (CRM_Utils_Array::value('required', $field) or
-            CRM_Utils_Array::value($fieldName, $this->_params['fields'])
-          ) {
-            $select[] = "{$field['dbAlias']} as {$tableName}_{$fieldName}";
-            $this->_columnHeaders["{$tableName}_{$fieldName}"]['type'] = CRM_Utils_Array::value('type', $field);
-            $this->_columnHeaders["{$tableName}_{$fieldName}"]['no_display'] = CRM_Utils_Array::value('no_display', $field);
-            $this->_columnHeaders["{$tableName}_{$fieldName}"]['title'] = CRM_Utils_Array::value('title', $field);
-          }
-        }
-      }
+  /**
+   * Adjust query for the activity_contact table.
+   *
+   * As this is just a join table the ID we REALLY care about is the activity id.
+   *
+   * @param string $tableName
+   * @param string $tableKey
+   * @param string $fieldName
+   * @param string $field
+   *
+   * @return string
+   */
+  public function selectClause(&$tableName, $tableKey, &$fieldName, &$field) {
+    if ($this->currentLogTable == 'log_civicrm_activity_contact' && $fieldName == 'id') {
+      $alias = "{$tableName}_{$fieldName}";
+      $select[] = "{$tableName}.activity_id as $alias";
+      $this->_selectAliases[] = $alias;
+      return "activity_id";
     }
-    $this->_select = 'SELECT ' . implode(', ', $select) . ' ';
   }
 
   public function where() {
@@ -257,15 +233,6 @@ class CRM_Logging_ReportSummary extends CRM_Report_Form {
     $sql = "CREATE TEMPORARY TABLE civicrm_temp_civireport_logsummary ( {$tempColumns} ) ENGINE=HEAP";
     CRM_Core_DAO::executeQuery($sql);
 
-    $logDateClause = $this->dateClause('log_date',
-      CRM_Utils_Array::value("log_date_relative", $this->_params),
-      CRM_Utils_Array::value("log_date_from", $this->_params),
-      CRM_Utils_Array::value("log_date_to", $this->_params),
-      CRM_Utils_Type::T_DATE,
-      CRM_Utils_Array::value("log_date_from_time", $this->_params),
-      CRM_Utils_Array::value("log_date_to_time", $this->_params));
-    $logDateClause = $logDateClause ? "AND {$logDateClause}" : NULL;
-
     $logTypes = CRM_Utils_Array::value('log_type_value', $this->_params);
     unset($this->_params['log_type_value']);
     if (empty($logTypes)) {
@@ -288,7 +255,7 @@ class CRM_Logging_ReportSummary extends CRM_Report_Form {
         (!in_array($this->getLogType($entity), $logTypes) &&
           CRM_Utils_Array::value('log_type_op', $this->_params) == 'notin')
       ) {
-        $this->from($entity);
+        $this->currentLogTable = $entity;
         $sql = $this->buildQuery(FALSE);
         $sql = str_replace("entity_log_civireport.log_type as", "'{$entity}' as", $sql);
         $sql = "INSERT IGNORE INTO civicrm_temp_civireport_logsummary {$sql}";
@@ -296,6 +263,8 @@ class CRM_Logging_ReportSummary extends CRM_Report_Form {
       }
     }
 
+    $this->currentLogTable = '';
+
     // add computed log_type column so that we can do a group by after that, which will help
     // alterDisplay() counts sync with pager counts
     $sql = "SELECT DISTINCT log_type FROM civicrm_temp_civireport_logsummary";
@@ -374,10 +343,14 @@ ORDER BY log_civicrm_entity_log_date DESC {$this->_limit}";
     if (!empty($this->_logTables[$entity]['bracket_info'])) {
       if (!empty($this->_logTables[$entity]['bracket_info']['entity_column'])) {
         $logTable = !empty($this->_logTables[$entity]['table_name']) ? $this->_logTables[$entity]['table_name'] : $entity;
+        if (!empty($this->_logTables[$entity]['bracket_info']['lookup_table'])) {
+          $logTable = $this->_logTables[$entity]['bracket_info']['lookup_table'];
+        }
         $sql = "
 SELECT {$this->_logTables[$entity]['bracket_info']['entity_column']}
   FROM `{$this->loggingDB}`.{$logTable}
  WHERE  log_date <= %1 AND id = %2 ORDER BY log_date DESC LIMIT 1";
+
         $entityID = CRM_Core_DAO::singleValueQuery($sql, array(
           1 => array(
             CRM_Utils_Date::isoToMysql($logDate),
index 5b984acf048dae78b8f73238bae3eb1016bda3c5..42f4c1ff39627b7c5d33f99be5c99717f2d66a92 100644 (file)
@@ -247,14 +247,9 @@ class CRM_Report_Form_Contact_LoggingSummary extends CRM_Logging_ReportSummary {
 
   /**
    * Generate From Clause.
-   *
-   * @param string $logTable
    */
-  public function from($logTable = NULL) {
-    static $entity = NULL;
-    if ($logTable) {
-      $entity = $logTable;
-    }
+  public function from() {
+    $entity = $this->currentLogTable;
 
     $detail = $this->_logTables[$entity];
     $tableName = CRM_Utils_Array::value('table_name', $detail, $entity);