Not so clear after all :-(
If I understand this correctly from Ingo's comments, calls within template controls are cached in the template layer, so <% if RelatedPages %><% control RelatedPages %>... is OK.
With a bit of luck, resultsets are cached in MySQL, depending on hosting... But to up performance within the model/controller we should provide our own caching? So to access a resultset from throughout code, we should do something like this:
Well, I just got off the phone to the SilverStripe guys and was told that DataObjects get cached as do relationships. So the database isn't repeatedly hit for the same data over and over if you do <% if Children %> and <% control Children %>.
If you do ?showqueries in the URL of a page, you will see that there are not identical queries one after the other where you do this in your template either.
So if I understand correctly there is a cache in the templating engine which grabs everything.
This leaves us with:
- many_manys and has_manys are cached in templates, but not in the php code
- has_ones are cached both in templates and code (by the virtue of having a dedicated cache)
- Children are also cached in both (dedicated cache too)