Answers.Body: <p>You could just setup a criteria model in your “categories” for-loop, prepared to query for the users related to that category. And then use the <code>total()</code> method to get the count.</p>
  
  <pre class="lang-php prettyprint-override"><code>foreach($category as $interest) {
      $user_criteria = craft()-&gt;elements-&gt;getCriteria(ElementType::User);
      $user_criteria-&gt;relatedTo = $interest-&gt;id;
      $count = $user_criteria-&gt;total();
  
      $interestArray[$interest-&gt;title] = $count;
  }
  </code></pre>
  
  <p>Using the <code>total()</code> method is a lot faster than <code>find()</code>, the underlaying SQL which is necessary to get the amount of rows performs better and Craft also doesn’t have to populate the Entry models with all the data.</p>
  
  <p><em>(Not sure why @LukePearce deleted his answer, where he basically suggested to do the same thing.)</em></p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-06-30T18:49:15.273Z
Answers.Text: I re-read the question and thought it was asking for something different, I have now re-read again and realised I was correct... oops!
Answers.UserDisplayName: Luke Pearce
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-07-04T09:57:19.063Z
Answers.Text: @carlcs thanks for the reply and I can see this would wotk normally. The only thing is we are using a dynamic checkbox field for the user interests. This is created from the categories group. So there is no related category field being used directly. Is there a way to check the dynamic checkbox field for the $interests->id in the criteria?
Answers.UserDisplayName: Lettie
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-07-04T10:02:27.103Z
Answers.Text: @Lettie nope, a checkboxes field stores an array of IDs serialized as JSON, so there's no good way to use that data in a SQL query.
Answers.UserDisplayName: carlcs
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-07-04T10:04:13.500Z
Answers.Text: @carlcs yes sorry just read your previous post http://craftcms.stackexchange.com/questions/11991/how-to-return-entries-based-on-checkboxes-field-criteria cheers
Answers.UserDisplayName: Lettie
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-06-30T17:27:32.760Z
Answers.LastActivityDate: 2016-06-30T18:57:29.357Z
Answers.LastEditDate: 2016-06-30T18:57:29.357Z
Answers.UserDisplayName: carlcs
Body: <p>Hi I have a plugin that loops through users to find out their interests. Counts the number of interests in total for each interest and displays this in a widget on the dashboard with the interest name and amount of users with that interest. The code I have works but fails with a max execution time and only pulls out minimal results for each interest. Is there a way to do this more efficiently so the script does not timeout. This is what I have so far but I'm sure looping through 20k+ users and checking each interest field to see if the category id is in it is highly inefficient. Cheers.</p>
  
  <pre><code>public function getInterestRank()
  {
      $criteria = craft()-&gt;elements-&gt;getCriteria(ElementType::Category);
      $criteria-&gt;group = 'interestTags';
      $category = $criteria-&gt;find();
  
      //Get all users
      $user_criteria = craft()-&gt;elements-&gt;getCriteria(ElementType::User);
      $users = $user_criteria-&gt;find();
  
      $interestArray = array();
  
      foreach($category as $interest)
      {
          $title = $interest['title'];
          $count = 0;
  
          foreach($users as $user)
          {
              if($user['interests']) {
                  if(in_array($interest['id'], $user['interests']))
                  {
                      $count = $count+1;
                  }
              }
          }
          $interestArray[$title] = $count;
      }
  
      arsort($interestArray);
      return ($interestArray);
  }
  </code></pre>
  
Tags: <plugin-development><users><plugins>
Title: Efficient way of looping through a large amount of users?
ThreadText: # Efficient way of looping through a large amount of users?
  
  (Asked by: username_0 on 2016-06-30)
  
  Hi I have a plugin that loops through users to find out their interests. Counts the number of interests in total for each interest and displays this in a widget on the dashboard with the interest name and amount of users with that interest. The code I have works but fails with a max execution time and only pulls out minimal results for each interest. Is there a way to do this more efficiently so the script does not timeout. This is what I have so far but I'm sure looping through 20k+ users and checking each interest field to see if the category id is in it is highly inefficient. Cheers.
  
  ```
  public function getInterestRank()
  {
      $criteria = craft()->elements->getCriteria(ElementType::Category);
      $criteria->group = 'interestTags';
      $category = $criteria->find();
  
      //Get all users
      $user_criteria = craft()->elements->getCriteria(ElementType::User);
      $users = $user_criteria->find();
  
      $interestArray = array();
  
      foreach($category as $interest)
      {
          $title = $interest['title'];
          $count = 0;
  
          foreach($users as $user)
          {
              if($user['interests']) {
                  if(in_array($interest['id'], $user['interests']))
                  {
                      $count = $count+1;
                  }
              }
          }
          $interestArray[$title] = $count;
      }
  
      arsort($interestArray);
      return ($interestArray);
  }
  
  ```
  
  **Tags:** plugin-development, users, plugins
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2016-06-30. Score: 3
  
  You could just setup a criteria model in your “categories” for-loop, prepared to query for the users related to that category. And then use the `total()` method to get the count.
  
  ```php
  foreach($category as $interest) {
      $user_criteria = craft()->elements->getCriteria(ElementType::User);
      $user_criteria->relatedTo = $interest->id;
      $count = $user_criteria->total();
  
      $interestArray[$interest->title] = $count;
  }
  
  ```
  
  Using the `total()` method is a lot faster than `find()`, the underlaying SQL which is necessary to get the amount of rows performs better and Craft also doesn’t have to populate the Entry models with all the data.
  
  *(Not sure why @username_2 deleted his answer, where he basically suggested to do the same thing.)*
  
  > **Comments:**
  > **username_2**: I re-read the question and thought it was asking for something different, I have now re-read again and realised I was correct... oops!  
  > **username_0**: @username_1 thanks for the reply and I can see this would wotk normally. The only thing is we are using a dynamic checkbox field for the user interests. This is created from the categories group. So there is no related category field being used directly. Is there a way to check the dynamic checkbox field for the $interests->id in the criteria?  
  > **username_1**: @username_0 nope, a checkboxes field stores an array of IDs serialized as JSON, so there's no good way to use that data in a SQL query.  
  > **username_0**: @username_1 yes sorry just read your previous post http://craftcms.stackexchange.com/questions/11991/how-to-return-entries-based-on-checkboxes-field-criteria cheers  
  
  ---
  
  