저는 상당히 복잡한 데이터 세트를 가져온 다음 내보내기 관리자 클래스에 의해 CSV 파일에 배치되는 심포니 저장소 메소드를 가지고 있습니다. 내보내기 작업을 처리하는 전체 코드를 넣고 싶지는 않지만 쿼리가 느려지는 지점을 정확히 찾아낼 수 있었기 때문에 코드 자체보다는 쿼리를 더 빠르게 만드는 다른 대안에 대해 질문하고 있습니다. 따라서 가져온 데이터는 여러 "멤버십"과 "사용자"를 포함하는 일부 "사이트" 데이터입니다.그래서 문제는 내 쿼리가 사용자 정보를 사이트에 연결하려고 할 때 실행 속도가 느려진다는 것입니다. 다음과 같습니다:
$qb->leftJoin('s.memberships', 'ex_sm', 'WITH', 'ex_sm.revokedAt IS NULL'); $qb->leftJoin('ex_sm.user', 'ex_jappr', 'WITH', 'ex_sm.approverJobReactiveWeight는 NULL이 아닙니다');
몇 가지 언급할 사항(시도했거나 도움이 될 것이라고 생각한 것):
6가지 다른 사용자 유형이 있습니다. 이제 위의 사용자 유형을 가져오기 위해 스크립트를 호출하기만 하면 되며 데이터를 반환하는 데 33분이 걸렸습니다. 우리는 512개 사이트에 대해 이야기하고 있는데 이는 거대한 데이터 모음이 아닙니다.그래서 내 질문은: 이렇게 복잡한 쿼리에서 leftJoins에 대한 호출 수를 단순화하거나 줄이고 어떻게든 성능을 향상시킬 수 있는 또 다른 DQL이나 Doctrine 방법이 있습니까?
업데이트: 문제가 색인에 있다고 생각하여 관계에 대한 몇 가지 세부 정보를 제공했습니다. "멤버십" 엔터티는 "access"라는 테이블에서 나오며 해당 모델에서 사용자와의 관계는 다음과 같습니다.
/*** 이 멤버십이 캡슐화하는 사용자입니다. * * @ORMManyToOne(targetEntity="User", inversedBy="siteMemberships", cascade={"persist"}) * @ORMJoinColumn(name="security_identity_id", referencedColumnName="id") * * @var 사용자*/ 보호된 $user;
이것은 "security_identity_id" 열에 할당된 인덱스의 스크린샷입니다.
관련 사용자는 멤버십을 가리키는 관계가 있는 사용자 테이블에서 나옵니다
/*** @ORMOneToMany(targetEntity="SiteMembership", mappedBy="user", cascade={"persist"}, fetch="EXTRA_LAZY")*/ 보호된 $siteMemberships;
기본 키는 엔터티의 "id"입니다.이것이 상황을 더 나은 관점으로 보기를 바랍니다. 나는 SQL 전문가는 아니지만 내가 찾은 모든 것을 시도했고 지금까지 알아낼 수 있습니다.
업데이트: 실행된 쿼리는 다음과 같습니다.
SELECT s0_.name AS name_0, s0_.id AS id_1, GROUP_CONCAT(DISTINCT u1_.name SEPARATOR ', ') AS sclr_2 FROM 사이트 s0_ LEFT JOIN 액세스 a2_ ON s0_.id = a2_.entity_id AND a2_.type IN ('site_member') 그리고 (a2_.revoked_at는 NULL입니다) LEFT JOIN 사용자 u1_ ON a2_.security_identity_id = u1_.id AND (a2_.approver_job_reactive_weight는 NULL이 아닙니다)
이렇게 하면 회원 자격 및 사용자 권한과 함께 첫 번째 사이트 기록이 반환됩니다. 하지만 이 행조차 2분 이상 걸립니다.
(멤버 엔터티) 테이블에 접근하기 위한 테이블 생성 정보는 다음과 같습니다
'CREATE TABLE `액세스`( `id` int(11) NOT NULL AUTO_INCREMENT, `buddy_id` int(11) 기본 NULL, `security_identity_id` int(11) 기본 NULL, `revoked_at` 날짜/시간 DEFAULT NULL, `created_at` 날짜/시간은 NULL이 아닙니다. `updated_at` 날짜/시간은 NULL이 아닙니다. `type` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `approver_job_reactive_weight` int(11) 기본 NULL, `entity_id` int(11) 기본 NULL, 기본 키(`id`), 고유 키 `access_idx`(`type`,`security_identity_id`,`entity_id`,`buddy_id`), KEY `IDX_6692B54395CE8D6`(`buddy_id`), KEY `IDX_6692B54DF9183C9`(`security_identity_id`), KEY `IDX_6692B5481257D5D`(`entity_id`), KEY `idx_revoked_id_approver_type`(`revoked_at`, `entity_id`, `approver_job_reactive_weight`, `approver_job_planned_weight`, `type`), KEY `idx_user_site_access`(`revoked_at`, `security_identity_id`, `buddy_id`, `type`), KEY `idx_user`(`security_identity_id`), KEY `idx_user_id`(`security_identity_id`), 제약 조건 `FK_6692B54DF9183C9` 외래 키(`security_identity_id`) 참조 `user`(`id`) ) 엔진=InnoDB AUTO_INCREMENT=262441 기본 CHARSET=utf8 COLLATE=utf8_unicode_ci'
관련 없는 열을 일부 삭제했습니다.
당신은 많은 캠프에 참여하고 있습니다. 그래서 속도가 느려지는 거죠
으아악회원 수가 많을수록 쿼리 속도가 느려집니다. 전체 쿼리에 대해서는 모르지만 멤버십 테이블에서 쿼리를 시작하거나 두 번째 쿼리를 수행할 수 있습니다.
완료되면
LEFT JOIN
时,ON
需要说明表是如何关联的。WHERE
子句通常有IS NULL
或IS NOT NULL
는 오른쪽 행을 제외할지 포함할지를 나타냅니다.LEFT JOIN
和INNER JOIN
的速度基本相同。但我需要查看索引 (SHOW CREATE TABLE
) 和SELECT
다른 문제가 있는지 확인하기 위한 SQL입니다.더보기
교체
으아악그리고
으아악