2
저는 오랫동안이 문제로 고생했습니다. 이 쿼리는 세트 작은 데이터에 매우 빠르게 실행되지만 테이블이 100,000 + 행 성장할 때 실행하는 데 몇 분에 30에서 취 "null이 아님"을 사용하는 왼쪽 조인 쿼리의 최적화
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
는 기본적으로 사용자가 레코드 (계정을 소유 한 모든 행을 반환해야합니다. assigned_user_id)이거나 레코드와 연관된 그룹의 구성원입니다 (securitygroup_join.id가 널이 아님). 이 쿼리는 프레임 워크에 의해 특정 방식으로 구축되어 일부 제약에 직면합니다. 쉽게 구현할 수없는 가능한 솔루션은이를 UNION으로 변경하는 것입니다. 그 경로를 피하고 싶습니다. 과거에는 "어디에서 ... in"절을했지만 그보다 더 나쁜 수행을했습니다. 필요에 따라 조인, where 절을 추가하거나 인덱스를 조작 할 수 있지만 쿼리 구조의 다른 급격한 변경은 쉽게 수행 할 수 없습니다.
+1 : 시도해 볼만한 가치가 있습니다. MS SQL Server는 이것을 매우 잘 최적화합니다. MySQL도 시도해 봅니다. – MatBailie
securitygroups_records 테이블에서 700k 행을 가진 db에 대해 제안 된 변경 사항은 약 3.2 초에서 실행되지만 원래 쿼리는 17.8 초에서 실행됩니다. 나는 그것이 좋은 개선이라고 말한다. 나는 처음부터 존재하지 않는다고 생각하지 않았다. 감사! – egg
좋습니다! 다행히 도울 수있어. –