2012-12-05 2 views
0

나는 리소스를 zapping하고 그것을 다시 작성해야하는 긴 쿼리가 있습니다. 명백한 문제는 where 절에 "not in"을 사용하는 것입니다. 초기 생각은 모든 자체 조인을 수행하지 않고 하위 쿼리에 "존재하지 않음"을 수행하여 다시 작성하는 것입니다. 그 일에 대한 어떤 생각이든, 아니면 그 생각보다 더 효율적인 생각일까요?이 mysql select 쿼리를 작성하는 더 좋은 방법은

SELECT a.referenceid, 
     a.memberid AS d1, 
     b.memberid AS d2, 
     c.memberid AS d3, 
     d.memberid AS d4, 
     e.memberid AS d5, 
     f.memberid AS d6 
FROM jos_comprofiler_members AS a FORCE INDEX (aprm) 
     LEFT JOIN jos_comprofiler_members AS b FORCE INDEX (aprm) 
       ON a.memberid = b.referenceid 
       AND b.accepted = 1 
       AND b.pending = 0 
     LEFT JOIN jos_comprofiler_members AS c FORCE INDEX (aprm) 
       ON b.memberid = c.referenceid 
       AND c.accepted = 1 
       AND c.pending = 0 
     LEFT JOIN jos_comprofiler_members AS d FORCE INDEX (pamr) 
       ON c.memberid = d.referenceid 
       AND d.accepted = 1 
       AND d.pending = 0 
     LEFT JOIN jos_comprofiler_members AS e FORCE INDEX (pamr) 
       ON d.memberid = e.referenceid 
       AND e.accepted = 1 
       AND e.pending = 0 
     LEFT JOIN jos_comprofiler_members AS f FORCE INDEX (pamr) 
       ON e.memberid = f.referenceid 
       AND f.accepted = 1 
       AND f.pending = 0 
WHERE a.referenceid = 1593 
     AND a.accepted = 1 
     AND a.pending = 0 
     AND f.memberid = 1593 
     AND b.memberid NOT IN (1593, a.memberid) 
     AND c.memberid NOT IN (1593, a.memberid, b.memberid) 
     AND d.memberid NOT IN (1593, a.memberid, b.memberid, c.memberid) 
     AND e.memberid NOT IN (
      1593, a.memberid, b.memberid, c.memberid, d.memberid) 
     AND f.memberid NOT IN (1593, a.memberid, b.memberid, c.memberid, 
           d.memberid, e.memberid) 
LIMIT 0, 1 
+0

WOAH! 그게 많이 ... –

+0

죄송 합니다만,이 조인의 요점은 무엇입니까에 대한 명확하지 않습니다 .. – Kermit

+0

동일한 테이블에서 동일한 6 개의 memberID를 얻으려고합니까? 이 쿼리의 목표에 대한 자세한 정보를 제공해 주시겠습니까? – Jeffrey

답변

0

조회에 1593. 수사적 질문의 거리 6 내의 모든 멤버를 찾고 있습니다 : 여기

는 쿼리의이 분리 육도 관련이 있습니까?

일반적으로 SQL에서 이러한 목록을 찾으려면 재귀 쿼리 나 SELECT가 아닌 일부 구문 (루프, 커서)이 필요합니다. MySQL이 not in을 처리하는 방법에 대해서는 목록이 가변 멤버로 구성되어 있는지 잘 모르겠습니다. 그러나, 그것은 각각에 대해 어떤 종류의 중첩 루프 조인을하고 있다고 의심합니다.

제안 : not in 문을 on 절로 이동하십시오. 예 :

LEFT JOIN jos_comprofiler_members AS c FORCE INDEX (aprm) 
      ON b.memberid = c.referenceid 
      AND c.accepted = 1 
      AND c.pending = 0 
      AND (c.memberId <> b.MemberId an c.MemberId <> a.MemberId and c.MemberId <> 1593) 

이렇게하면 상황이 개선 될 수 있습니다. 아니면 그들을 악화 시키십시오. 그러나 그것은 하나의 아이디어입니다.

+0

고든에게 감사 드린다. 나는 질의가 만들어지는 곳을 마침내 추적 할 수 있었다. 맞다. 프로필을 보는 회원과 프로필 소유자 사이의 분리도를 결정하십시오. 우리는 그 기능이 필요하지 않기 때문에 당분간 기능에 대한 질의를 주석 처리했습니다. 어떤 이유로 든 기능이 다시 필요하다면 다시 작성해야하지만 현재는 마음에서 벗어난다. 나는 여전히 도움이 될 수 없지만 어떻게 고쳐야 가장 효율적이고 가장 효율적인 방법인지 궁금해합니다. –

+0

@SpencerFraise. . . 멤버 하나만 찾고 있다면 가장 좋은 방법은 멤버를 임시 테이블에로드 한 다음 while 루프에서 멤버를 반복적으로 한 번에 한 번씩 분리하여 추가하는 것입니다. –

관련 문제