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

Creating contacts is slow, part 1 of 2: Calculating Greetings

    Details

    • Type: Bug
    • Status: Done/Fixed
    • Priority: Minor
    • Resolution: Fixed/Completed
    • Affects Version/s: 4.7.24
    • Fix Version/s: 4.7.25
    • Component/s: Core CiviCRM
    • Labels:
    • Versioning Impact:
      Patch (backwards-compatible bug fixes)
    • Documentation Required?:
      None
    • Funding Source:
      Contributed Code
    • Verified?:
      No
    • How it works currently:
      Contacts take a long time to create.
    • How it should work:
      Contacts should get created 2-3x faster
    • Acceptance Criteria:
      All unit tests pass.

      Description

      It currently takes 21 seconds to create 200 contacts (CRM_Contact_BAO::create()).  I was able to optimize this down to 10 seconds under normal circumstances, and 7 seconds on my intended use case (CLI imports).

      I ran a profiler and found that of the 21 seconds, only 1.2 seconds is spent on adding the contact.  3.7 seconds goes to clearing the smart group cache, and 13.9 seconds is spent on calculating the greeting tokens.  This PR focuses on the greeting tokens.

      Greetings tokens are calculated by loading a contact's data into an array (via DAO->find()), replacing tokens with that data, then checking if there are any unreplaced tokens.  If any tokens are unreplaced, Civi makes two (very expensive!) calls to CRM_Contact_BAO_Query.  Since non-contact tokens in greetings are rare, this should happen only rarely.

      Unfortunately, the greetings code doesn't account for the fact that fields that are NULL in the database won't appear in the object created by DAO->find().  Since the default addressee greeting has 5 tokens, you end up with a very slow greeting replacement unless your contacts have all of the following: prefix, suffix, first name, middle name, last name.

      Finally, there need not be two calls to CRM_Contact_BAO_Query; one is sufficient.

      By identifying and removing contact tokens whose values are null, we avoid the expensive calls; this shaves 12 seconds of the original 21.  On the rare occasion such a call is needed, we still save 6 seconds by calling the function once instead of twice.

        Attachments

          Activity

            People

            • Assignee:
              monish.deb Monish Deb
              Reporter:
              palantejon Jon K Goldberg
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: