I decided to have a look into database usage by SilverStripe as I'm building a fairly large website and wanted to make sure it could scale properly.
I've got a page thats very simple at the moment but understandably had a number of queries to build it. I turned on logging on my database to see what was being requested.
The queries that I thought might be problematic (the ones I do) aren't that often but the database has about 50 queries similar to this:
SELECT conname,pg_catalog.pg_get_constraintdef(r.oid, true)
FROM pg_catalog.pg_constraint r WHERE r.contype = 'c' AND conname = $1 ORDER BY 1;
About 10 queries for the SiteTree and about 10 or so for Member. Now it's not a problem at the moment but if each page is loading about 100 queries (there are others on top of these) I'm going to have some issues when I launch.
Whats causing all these queries? Can I do anything to lower them, especially the one above.
Also, if I do:
$data = DataObject::get()->filter('field1' => 'value1');
if ($data->exists()) {
$one = $data->filter('field2' => 'value2');
// do something
$two = $data->filter('field2' => 'value3')->First();
echo $two->Has_One_Field()->Field //accessing a has_one relationship
//do something
}
Will that result in 4 queries or just one and the two other filters are just searching the DataList
thats already been produced?
First of all, when you are logged in as a member, those member-queries are executed. If you're not logged in, those queries will not be executed, so that'll save you 10 queries.
Your second question, each new added filter, will only return a new DataList, not actually executing the final query, until you echo them. Although your example won't work, as $two is a DataList, not a DataObject. To get the actual item, you need to do $two->HasOneObject()->Field
, but that aside.
To lower these queries, you might consider caching. But to be honest, I shouldn't worry too much about it. A database is meant for this kind of things. If you actually loaded them as objects in PHP, then the problem would be way worse, as it would start eating memory.
Another option, would be to extend page, and cache the results of certain queries into variable ArrayList objects, so you can filter them from memory. In theory this is faster, but requires PHP to do more work, which can slow down things when it gets big.