Bad Performance with collection of data
tombien opened this issue · 4 comments
Hello,
I have a translatable model.
I have a JSON response with about 150 items of this model.
There is a very big difference in response time (1sec in default language vs 9sec where site is in another language).
For example:
function onGetProducts() {
$tests = Product::select('id', 'code', 'name', 'description')->take(100)->get();
return Response::json($tests);
}
Product is a model implementing RainLab.Translate.Behaviors.TranslatableModel
I call this function by ajax. When site is on default language //example.cz/cs/products - it takes about 1 sec.
On //example.cz/en/products - it takes about 8-10sec.
I tested it for only 10 items and it is 500ms vs 1,4s. I think this is a noticeable difference in performance, when using this plugin.
This looks like it could be related to the n+1 query problem. It is overcome in Laravel using eager loading. This is where the code uses the with
method to eager load the relations.
$tests = Product::with('translations')->select('id', 'code', 'name', 'description')->take(100)->get();
Alternatively, you can do this "after the fact" using the loadMissing
method.
$tests = Product::select('id', 'code', 'name', 'description')->take(100)->get();
$tests->loadMissing('translations');
return Response::json($tests);
I hope this helps.
@daftspunk - thank you very much, it helps. Is this a standard approach to translatable data collection (for me to keep on mind for future) or you will make some changes in plugin?
No problem. This is the standard approach; Laravel wants us to be explicit about the queries. The n+1 problem is something to always be mindful of when working with models and their relationships. In this case, the translate plugin stores its translated messages as a relation, so it is important to be mindful of that.