Friday 04 July 2014 12:35:55 pm
Diving into eZ Publish 5 SearchService
Having implemented several eZ 5 projects using the new stack only, mainly using 5.2 and 2014.01 versions, I have seen a considerable performance degradation of SearchService::findContent with increasing number of content objects. Even simple things as fetching a subtree for a meta navigation became intolerably slow - a behavior I did not know from eZ 4.
When diving into SearchService::findContent I was very astonished to find out that it always retrieves ALL attributes in ALL languages, even when I would only be interested in the contentInfo - but alas, there is no asObjects flag as in Legacy to control this.
When investigating even further   I found out that in order to retrieve the full content objects, a huge PHP array is created based on the SQL table resulting from different joins. To give you an impression of the size of this array: for a search resulting in 24 hits, this array had 44,880 rows with 39 elements each, with highly redundant data.
This array is then processed using different additional arrays and finally combined into the resulting content objects. This process is obviously slow and scales badly. A single search returning a subtree with 70 objects took twice as long as searching four locations individually for the same objects.
When speaking to development, they admitted that there are performance problems, partly resulting from the language filter flag not yet being implemented. They made clear, however, that implementing an asObjects flag was never planned. In my opinion this decision is to be questioned.
I wonder how others are coping with SearchService? Are you experiencing similar performance problems? When do you use SearchService::findContent and how do you process the results? What alternatives do you use?
Speaking of alternatives: in 5.3 / 2014.03 SearchService::findLocations was introduced. It is much closer to the old fetches, better suited for the content tree structure, and as far my tests with smaller sites show, much faster. It returns locations with contentInfos only. An another alternative is LocationService::loadLocationChildren which retrieves the children of a given location. Intended mainly for the admin interface, it honors sorting, but lacks filtering. As a last resort (e.g. if you can't update), you can use a legacy closure to call legacy fetch functions.
In any case my advice would be: upgrade to 5.3 / 2014.05 and use SearchService::findLocations whenever possible.