I’ve struggled with this one for a long time. This query runs fairly fast on a smaller data set but when the tables grow to 100k+ rows it takes from 30s to several minutes to run:
SELECT accounts.id
, accounts.name
, ..etc..
FROM accounts
LEFT JOIN (
SELECT distinct secr.record_id as id
FROM securitygroups secg
INNER JOIN securitygroups_users secu
ON secg.id = secu.securitygroup_id
AND secu.deleted = 0
AND secu.user_id = 'seed_chris_id'
INNER JOIN securitygroups_records secr
ON secg.id = secr.securitygroup_id
AND secr.deleted = 0
AND secr.module = 'Accounts'
WHERE secg.deleted = 0
) securitygroup_join ON securitygroup_join.id = accounts.id
WHERE (( accounts.assigned_user_id ='seed_chris_id'
OR securitygroup_join.id is not null))
AND accounts.deleted=0
ORDER BY
accounts.date_entered
DESC LIMIT 0,21
Basically it should return all rows where the user owns the record (accounts.assigned_user_id) or is a member of a group associated to the record (securitygroup_join.id is not null). This query gets built in a particular way by the framework so facing some constraints. A possible solution that cannot be easily implemented would be to change this to a UNION. Would like to avoid that route. In the past did a “where…in” clause but that performed even worse. I can add to the join, where clause, or manipulate indexes as needed but any other drastic changes to the query structure cannot be easily done.
You could try a
WHERE EXISTSinstead of aLEFT JOIN. For example:I haven’t tested this, so it may not perform better, but it’s worth trying.