📜 ⬆️ ⬇️

Unobvious performance problems in Doctrine related to the hydration of objects

Recently, I implemented the API functions in a Symfony2 back-end project that uses Doctrine as the ORM.

And, as it sometimes happens, the speed of working out did not quite suit me. For a simple request, the response was generated in 7.2 seconds.


')
The first assumption is that some heavy queries are running somewhere. But through the profiler you can not see anything that could
to suggest where the problem was hidden. There are a lot of SQL queries, but all are fast, and their total execution time is only 223 milliseconds.





I go to the Timeline tab - it is clear that the problem occurs during the operation of the controller (there are literally 5 lines), but where exactly - it has not become clearer.



What turned out in the end.

It turned out that for generating data, some models (in the depth of long-written services) required connected one-to-many objects. The object was needed alone, but to access it, the entire ArrayCollection was raised from hundreds of objects.

Those. some of those quick queries returned hundreds of rows, on the basis of which Doctrine picked up hundreds of objects, and a lot of resources were needed for this.

This problem was solved simply. Having a little corrected the logic of the models, I had already prepared them at the time of accessing the related objects. Work time has become acceptable. But the problem, while it seems to me, can be quite typical and often arise in projects related to Doctrine. We need one bound object, all are initialized (not too noticeable to the developer).

It would be nice to control it somehow.

Therefore, I made a bundle that collects data on the time of hydration of objects inside Doctrine.

I think it may be useful for any project using the Symfony2 + Doctrine2 bundle.
debesha / DoctrineProfileExtraBundle (githab)

After installing the bundle, an additional badge appears in the profiler panel, in which you can see how much hydration was performed and how much time was spent on it:



Accordingly, in the example I gave at the beginning, the profiler looks more eloquent already - 5.5 seconds was spent on the hydration of objects.



And the same thing, but after optimization (which, as I said, was very simple. The most difficult thing was to locate the problem).
Hydration took 0.4 seconds (on my slow working computer).



I hope with my bandle I will save a lot of time for my colleagues.

Source: https://habr.com/ru/post/263103/


All Articles