skip to Main Content

I have a symfony repository method, which fetches a quite complex data set, which will then be placed in a CSV file by an export manager class. I don’t want to place the whole code of handling the export job, but I managed to chatch the point at which the query slows down, so my question is regarding any other alternative to make that query faster, rather than the code itself.
So the data fetched is some "site" data, which has multpiple "memberships", which then has a "user" . So the problem is, that when my query is trying to join the user information to the site, it slows down the execution. It looks like this:

$qb->leftJoin('s.memberships', 'ex_sm', 'WITH', 'ex_sm.revokedAt IS NULL');
$qb->leftJoin('ex_sm.user', 'ex_jappr', 'WITH', 'ex_sm.approverJobReactiveWeight IS NOT NULL');  

There are a few things (I tried or crossed through my mind could help) to mention:

  • I checked the tables, all the linked columns have an index and they are the same int data type.
  • I red an article about the DQL performance issues, where it was mentioned that overuse of DQL Left Join calls can kill performance as they re-map the same entity object over and over. A possible solution mentioned there was to fetch the main data set, and then looping through the collection, add the additional (joining data fields) to each element directly from the field’s entity class. That possibly could work (not sure how much impact it would have), the problem is that what I have is a really complex legacy code, I don’t want to touch the export manager’s logic, because that would require far too much testing. The export manager expects a query builder class, so I have to find a solution within the query itself.
  • The issue is defintely caused by the join, and not the ‘WITH’ clause or the addtional conditions. I tried to call the query with the plain leftJoin call, same result.
  • I know the leftJoin methods can be called chained to each other, the code looks this way because some of these call are used in if statements.
  • I spend 2 days trying all sort things found here and other websites.

There are 6 different user types, for now I just called the script fetching the one above and it took 33 minutes to return the data. We are talking about 512 sites, which is not a huge collection of data.
So my question is : Is there another DQL or any Doctrine way to simlify or reduce the call nulber of leftJoins in such a complex query, and somehow improve the performance?

Update:
I think the problem comes from indexes so I give some details on the relationships:
The ‘memberships’ entity comes from a table named ‘access’ the relationship to the user in its model looks like this:

/**
 * The user this membership encapsulates.
 *
 * @ORMManyToOne(targetEntity="User", inversedBy="siteMemberships", cascade={"persist"})
 * @ORMJoinColumn(name="security_identity_id", referencedColumnName="id")
 *
 * @var User
 */
protected $user; 

Here is a screenshot of the indexes assigend to the ‘security_identity_id’ columns
enter image description here

And the related User comes from a ‘user’ table having this relationship pointing to the membershipt

/**
 * @ORMOneToMany(targetEntity="SiteMembership", mappedBy="user", cascade={"persist"}, fetch="EXTRA_LAZY")
 */
protected $siteMemberships;

Primary key is ‘id’ in the entity.
Hope this gives a better view of the problem. I’m not an expert with sql, but tried everything I found and could understand so far.

2

Answers


  1. You joined many side. That is the slows down reason

    $qb->leftJoin('s.memberships', 'ex_sm', 'WITH', 'ex_sm.revokedAt IS NULL');
    

    more memberships, the slower your query. I don’t know how is full query but you can start the query from membership table or you can make a second query.

    Login or Signup to reply.
  2. When doing a LEFT JOIN, the ON needs to say how the tables are related. The WHERE clause normally has IS NULL or IS NOT NULL to say whether to exclude or include the right-hand rows.

    LEFT JOIN and INNER JOIN are mostly the same speed. But I need to see the indexes (SHOW CREATE TABLE) and the SQL of the SELECT to see if there are other issues.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search