Uploaded image for project: 'CiviCRM'
  1. CiviCRM
  2. CRM-13614

SQL query on dynamic group bracking database

    Details

    • Type: Bug
    • Status: Done/Fixed
    • Priority: Critical
    • Resolution: Fixed/Completed
    • Affects Version/s: 4.2.7
    • Fix Version/s: 4.5
    • Labels:

      Description

      Hi,

      We encountered an issue in using dynamic groups.
      The built query was killing are mysql database due to huge "left join" usage.
      So we made a patch on this file : civicrm/CRM/Contact/BAO/Query.php (function addGroupContactCache)

      Below the generated query :

      <pre>
      INSERT IGNORE INTO civicrm_group_contact_cache (group_id,contact_id) (
      SELECT 103 as group_id,
      contact_a.id as id
      FROM civicrm_contact contact_a
      LEFT JOIN civicrm_group_contact `civicrm_group_contact-25,74,97,28,58,33,34,35,39,38,40,41,43,37,44,46,45,47,48,49,50,51,52,53,23,101,102,26` ON contact_a.id = `civicrm_group_contact-25,74,97,28,58,33,34,35,39,38,40,41,43,37,44,46,45,47,48,49,50,51,52,53,23,101,102,26`.contact_id
      LEFT JOIN civicrm_group_contact_cache `civicrm_group_contact_cache_33` ON contact_a.id = `civicrm_group_contact_cache_33`.contact_id
      LEFT JOIN civicrm_group_contact_cache `civicrm_group_contact_cache_34` ON contact_a.id = `civicrm_group_contact_cache_34`.contact_id
      LEFT JOIN civicrm_group_contact_cache `civicrm_group_contact_cache_35` ON contact_a.id = `civicrm_group_contact_cache_35`.contact_id
      LEFT JOIN civicrm_group_contact_cache `civicrm_group_contact_cache_37` ON contact_a.id = `civicrm_group_contact_cache_37`.contact_id
      LEFT JOIN civicrm_group_contact_cache `civicrm_group_contact_cache_38` ON contact_a.id = `civicrm_group_contact_cache_38`.contact_id
      LEFT JOIN civicrm_group_contact_cache `civicrm_group_contact_cache_39` ON contact_a.id = `civicrm_group_contact_cache_39`.contact_id
      LEFT JOIN civicrm_group_contact_cache `civicrm_group_contact_cache_40` ON contact_a.id = `civicrm_group_contact_cache_40`.contact_id
      LEFT JOIN civicrm_group_contact_cache `civicrm_group_contact_cache_41` ON contact_a.id = `civicrm_group_contact_cache_41`.contact_id
      LEFT JOIN civicrm_group_contact_cache `civicrm_group_contact_cache_43` ON contact_a.id = `civicrm_group_contact_cache_43`.contact_id
      LEFT JOIN civicrm_group_contact_cache `civicrm_group_contact_cache_44` ON contact_a.id = `civicrm_group_contact_cache_44`.contact_id
      LEFT JOIN civicrm_group_contact_cache `civicrm_group_contact_cache_45` ON contact_a.id = `civicrm_group_contact_cache_45`.contact_id
      LEFT JOIN civicrm_group_contact_cache `civicrm_group_contact_cache_46` ON contact_a.id = `civicrm_group_contact_cache_46`.contact_id
      LEFT JOIN civicrm_group_contact_cache `civicrm_group_contact_cache_47` ON contact_a.id = `civicrm_group_contact_cache_47`.contact_id
      LEFT JOIN civicrm_group_contact_cache `civicrm_group_contact_cache_48` ON contact_a.id = `civicrm_group_contact_cache_48`.contact_id
      LEFT JOIN civicrm_group_contact_cache `civicrm_group_contact_cache_49` ON contact_a.id = `civicrm_group_contact_cache_49`.contact_id
      LEFT JOIN civicrm_group_contact_cache `civicrm_group_contact_cache_50` ON contact_a.id = `civicrm_group_contact_cache_50`.contact_id
      LEFT JOIN civicrm_group_contact_cache `civicrm_group_contact_cache_51` ON contact_a.id = `civicrm_group_contact_cache_51`.contact_id
      LEFT JOIN civicrm_group_contact_cache `civicrm_group_contact_cache_52` ON contact_a.id = `civicrm_group_contact_cache_52`.contact_id
      LEFT JOIN civicrm_group_contact_cache `civicrm_group_contact_cache_53` ON contact_a.id = `civicrm_group_contact_cache_53`.contact_id
      WHERE ( ( ( `civicrm_group_contact-25,74,97,28,58,33,34,35,39,38,40,41,43,37,44,46,45,47,48,49,50,51,52,53,23,101,102,26`.group_id IN (
      25,74,97,28,58,33,34,35,39,38,40,41,43,37,44,46,45,47,48,49,50,51,52,53,23,101,102,26 )
      AND `civicrm_group_contact-25,74,97,28,58,33,34,35,39,38,40,41,43,37,44,46,45,47,48,49,50,51,52,53,23,101,102,26`.status IN ("Added") ) OR ( `civicrm_group_contact_cache_33`.group_id = 33 OR
      `civicrm_group_contact_cache_34`.group_id = 34 OR `civicrm_group_contact_cache_35`.group_id = 35 OR `civicrm_group_contact_cache_37`.group_id = 37 OR `civicrm_group_contact_cache_38`.group_id = 38 OR
      `civicrm_group_contact_cache_39`.group_id = 39 OR `civicrm_group_contact_cache_40`.group_id = 40 OR `civicrm_group_contact_cache_41`.group_id = 41 OR `civicrm_group_contact_cache_43`.group_id = 43 OR
      `civicrm_group_contact_cache_44`.group_id = 44 OR `civicrm_group_contact_cache_45`.group_id = 45 OR `civicrm_group_contact_cache_46`.group_id = 46 OR `civicrm_group_contact_cache_47`.group_id = 47 OR
      `civicrm_group_contact_cache_48`.group_id = 48 OR `civicrm_group_contact_cache_49`.group_id = 49 OR `civicrm_group_contact_cache_50`.group_id = 50 OR `civicrm_group_contact_cache_51`.group_id = 51 OR
      `civicrm_group_contact_cache_52`.group_id = 52 OR `civicrm_group_contact_cache_53`.group_id = 53 ) ) ) AND (contact_a.is_deleted = 0) AND contact_a.id NOT IN (
      SELECT contact_id FROM civicrm_group_contact
      WHERE civicrm_group_contact.status = 'Removed'
      AND civicrm_group_contact.group_id = 103 ) )

      </pre>

      As you can see, there is an overhead use of "LEFT JOIN".
      Our patch limits this use to only one "LEFT JOIN" and use "IN (....)" instead of "OR" which is the same thing but much pretty to read.

        Attachments

          Activity

            People

            • Assignee:
              monish.deb Monish Deb
              Reporter:
              smalot Sebastien Malot
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: