Я долго боролся с этим. Этот запрос выполняется довольно быстро для меньшего набора данных, но когда таблицы увеличиваются до 100 000 строк +, для их выполнения требуется от 30 с до нескольких минут:
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
По сути, он должен возвращать все строки, в которых пользователь владеет записью (accounts.assigned_user_id) или является членом группы, связанной с записью (securitygroup_join.id не имеет значение null). Этот запрос определенным образом создается с помощью фреймворка, сталкивающегося с некоторыми ограничениями. Возможное решение, которое не может быть легко реализовано, состояло бы в том, чтобы изменить это на СОЮЗ. Хотел бы избежать этого маршрута. В прошлом делали предложение "где ... в", но это работало еще хуже. Я могу добавить в оператор join, where или манипулировать индексами по мере необходимости, но любые другие радикальные изменения в структуре запроса не могут быть легко выполнены.