Here's a simplified version of the queries I am running:

select
    ...
from
    editions
    join edition_events on edition_events.edition_id = editions.id
    join events on events.id = edition_events.event_id
    join (
        select
            event_id,
            array_agg(date_start),
            array_agg(date_end)
        from
            event_dates
        group by
            event_id
        ) as dates on dates.event_id = events.id
WHERE
    editions.id = ?;


These queries ran great with my test data (~1500 events).  Now that I'm starting to use a copy of the real data (~400,000 events, ~500,000 event_dates), my application is timing out before I get results back from the database.  I have added indexes on all relevant columns, which only helped a little bit.  I've narrowed down the problem to the subqueries that use aggregation.

Now the real version of these subqueries does things like time zone manipulation or a count instead of array_agg, so using a trigger to update a counter column is not practical in many instances.  The dates associated with events must be individual rows rather than stored as an array since they have a foreign key relationship with other tables.

What would be my best bet for improving performance here?  I understand that the subquery is being evaluated first, but I don't know which dates I actually need to look at until I've done the joins.  I have looked at lateral joins, but I am uncertain if they would help here (and most information I can find is along the lines of "look, new feature!").  Since I am still using 9.2, I don't want to ask to upgrade to 9.3+ if it won't actually solve my problem.


Question: Single entry with multiples pages
Answer: This is perfectly feasible in EE without any add-ons. Since EE doesn't really have a concept of pages, a single channel entry can appear at multiple URIs no problem - You'll just need to use some logic in your template to show the right entry.

There are lots of different ways to approach this, but let's say you want your URIs to be:

/products/widget-A/in/blue
/products/widget-A/in/red
/products/widget-B/in/blue
/products/widget-B/in/red


You could use a category or custom field to define the colours and then pipe the values through to a channel entries query. For example, with categories, your products/index template could look a bit like this (also using Low Seg2Cat to get the cat ID here):

{exp:channel:entries
    channel="products"
    disable="member_data|pagination"
    dynamic="no"
    category="{segment_4_category_id}"
    url_title="{segment_2}"
    limit="1"
}
    &lt;h1&gt;{title}&lt;/h1&gt;
{/exp:channel:entries}


You could do the same thing with a custom field, such as checkboxes or radio buttons and the search parameter. Just be a little bit careful that you don't pipe URI segments directly into a channel entries tag as this could be a (minor) security risk (exposing private entries etc if you're not careful). I would usually use Stash to pre-screen/normalise any incoming segments to prevent this.