<p>Your actual code is pretty effective – the problem is that it's potentially going to result in <em>a lot</em> of queries.</p>

<p>This is a good example of the so-called <em>N+1</em> query problem, where each iteration over the result set of a single query generates an additional number of queries. Depending on the number of elements involved, this issue can easily result in hundreds of queries, which can be a huge problem for performance.</p>

<p>The solution to the N+1 query problem is <a href="https://craftcms.com/docs/templating/eager-loading-elements" rel="nofollow noreferrer">eager loading</a>. With eager loading, you explicitly tell Craft which relational data it should include with the first query, unlike with the common "lazy loading" pattern where relational data is queried on a "need to use" basis.</p>

<p>Here's how your code could look, refactored to use eager loading:</p>

<pre><code>{% set results = block.result.find({
    with: ['infographicSection']
}) %}

{% for category, catEntries in results|group('infographicSection[0].title') %}
    {% set fullCat = catEntries[0].infographicSection[0] %}
    &lt;h1 class="{{fullCat.className}}"&gt;{{fullCat.title}}&lt;/h1&gt;
    &lt;p&gt;{{fullCat.body}}&lt;/p&gt;
    &lt;ul&gt;
        {% for entry in catEntries %}
            &lt;li&gt;{{entry.title}}&lt;/li&gt;
        {% endfor %}
    &lt;/ul&gt;
{% endfor %}
</code></pre>

<p>With something like the above, you should see the number of queries drop drastically (remember to turn on <a href="https://craftcms.com/support/dev-mode" rel="nofollow noreferrer"><code>devMode</code></a> in development and you'll see a profiling report in your browser's dev tools console, containing the total number of queries).</p>

CC BY-SA 3.0
2016-11-15T19:59:15.320Z
That's surprisingly easy! Thanks for the great response. Just noticing you're using the `[0]` syntax—is that a stylistic change or will that also be improving performance?
Darren Wood
CC BY-SA 3.0
2016-11-15T20:26:21.380Z
The brackets syntax is actually required with eager loading. The reason is that when you eager load a relational field (such as Entries, Assets or Categories), that field will no longer return an [ElementCriteriaModel](https://craftcms.com/docs/templating/elementcriteriamodel) instance, but a regular ol' array. The `.first()` method belongs to the ElementCriteriaModel class, and doesn't exist for arrays – hence the `[0]` instead. For an even better explanation, [check out the docs](https://craftcms.com/docs/templating/eager-loading-elements#accessing-eager-loaded-elements) :)
Mats Mikkel Rummelhoff
CC BY-SA 3.0
2016-11-15T12:09:39.140Z
2016-11-15T12:14:45.320Z
2016-11-15T12:14:45.320Z
Mats Mikkel Rummelhoff
<p>The basic idea is that I want to group my entries by category, but I want more than just the category title—I need the entire category entry. <a href="https://craftcms.stackexchange.com/questions/17706/ordering-related-items-by-cp-display-order">My previous post alludes to this</a>, but I've since discovered the query I was doing there was returning all related entries regardless of their existance in the <code>block.result</code> entry.</p>

<p>I'm currently doing this—which is exactly what I want, but it doesn't see very efficient... Is there a better way?</p>

<pre><code>{% set results = block.result %}
{% for category, catEntries in results | group('infographicSection.first().title') %}
    {% set fullCat = craft.categories.title(category).first() %}
    &lt;h1 class="{{fullCat.className}}"&gt;{{fullCat.title}}&lt;/h1&gt;
    &lt;p&gt;{{fullCat.body}}&lt;/p&gt;
    &lt;ul&gt;
    {% for entry in catEntries %}

        &lt;li&gt;{{entry.title}}&lt;/li&gt;
    {% endfor %}
    &lt;/ul&gt;
{% endfor %}
</code></pre>

CC BY-SA 3.0
2016-11-15T10:40:47.907Z
https://craftcms.com/docs/templating/eager-loading-elements  should help reduce queries
Krzysztof Boduch
<templating><categories><performance><queries><group>
Better way to group by category and include full category entry
# Better way to group by category and include full category entry

(Asked by: username_0 on 2016-11-15)

The basic idea is that I want to group my entries by category, but I want more than just the category title—I need the entire category entry. My previous post alludes to this, but I've since discovered the query I was doing there was returning all related entries regardless of their existance in the block.result entry.
I'm currently doing this—which is exactly what I want, but it doesn't see very efficient... Is there a better way?
{% set results = block.result %}
{% for category, catEntries in results | group('infographicSection.first().title') %}
    {% set fullCat = craft.categories.title(category).first() %}
    {{fullCat.title}}
    {{fullCat.body}}
    
    {% for entry in catEntries %}

        {{entry.title}}
    {% endfor %}
    
{% endfor %}

**Tags:** templating, categories, performance, queries, group

> **Comments:**
> **username_1**: https://craftcms.com/docs/templating/eager-loading-elements  should help reduce queries  

---

## 1 answers

### Answer by username_2 on 2016-11-15. Score: 2 | Accepted answer

Your actual code is pretty effective – the problem is that it's potentially going to result in a lot of queries.
This is a good example of the so-called N+1 query problem, where each iteration over the result set of a single query generates an additional number of queries. Depending on the number of elements involved, this issue can easily result in hundreds of queries, which can be a huge problem for performance.
The solution to the N+1 query problem is eager loading. With eager loading, you explicitly tell Craft which relational data it should include with the first query, unlike with the common "lazy loading" pattern where relational data is queried on a "need to use" basis.
Here's how your code could look, refactored to use eager loading:
{% set results = block.result.find({
    with: ['infographicSection']
}) %}

{% for category, catEntries in results|group('infographicSection[0].title') %}
    {% set fullCat = catEntries[0].infographicSection[0] %}
    {{fullCat.title}}
    {{fullCat.body}}
    
        {% for entry in catEntries %}
            {{entry.title}}
        {% endfor %}
    
{% endfor %}

With something like the above, you should see the number of queries drop drastically (remember to turn on devMode in development and you'll see a profiling report in your browser's dev tools console, containing the total number of queries).

> **Comments:**
> **username_0**: That's surprisingly easy! Thanks for the great response. Just noticing you're using the `[0]` syntax—is that a stylistic change or will that also be improving performance?  
> **username_2**: The brackets syntax is actually required with eager loading. The reason is that when you eager load a relational field (such as Entries, Assets or Categories), that field will no longer return an [ElementCriteriaModel](https://craftcms.com/docs/templating/elementcriteriamodel) instance, but a regular ol' array. The `.first()` method belongs to the ElementCriteriaModel class, and doesn't exist for arrays – hence the `[0]` instead. For an even better explanation, [check out the docs](https://craftcms.com/docs/templating/eager-loading-elements#accessing-eager-loaded-elements) :)  

---

