2009-08-21 3 views
1

나는이를 최적화하는 방법에 대한 팁을 찾고 있어요 ....사용 제대로 조인

SELECT u.uid, 
     u.username, 
     u.nid, 
     wd.pay 
FROM  (users_data AS u 
      LEFT JOIN winners_data wd 
      ON u.nid = wd.nid 
       AND u.uid = wd.uid) 
     LEFT JOIN dp_node dn 
      ON u.nid = dn.nid 
WHERE u.uid = ".$val." 
     AND ((dn.TYPE = 'event' 
       AND (SELECT Count(nid) 
        FROM tournament_event 
        WHERE nid = u.nid 
          AND type_value IN ('A','B','C')) > 0) 
       OR (dn.TYPE = 'new_event' 
        AND (SELECT Count(nid) 
         FROM user_tournament_event 
         WHERE nid = u.nid 
           AND type_0_value IN ('Y','X')) > 0)) 
ORDER BY nid ASC 

실제로 $의 발은 한 부분으로 한 번에 다음 쿼리 하나에서 오는 UID하지만 아무것도 없다 내 루프의.

는 leader_Jdump AS FROM (dump.uid) DISTINCT가

위의 질의에뿐만 아니라이 부분을 추가 할 수있는 방법이 있나요 덤프 SELECT? MySQL 레벨에서 할 수 있다면 더 빠를 것이라고 생각합니다.

+0

가독성을 위해 쿼리를 들여 썼을 가능성이 있습니다.이 형식에서는 두뇌에 어려움이 있습니다. – Zoidberg

+3

왼쪽부터 내 뇌가 뒤따 랐습니다. –

+0

여기에서 HTML이 지원되는지/포맷되었는지 확실하지 않습니다. 그래서 라이브 저널에 게시합니다. http://shantanuo.livejournal.com/64338.html – shantanuo

답변

4

이 시도 :

SELECT u.uid, u.username, u.nid, wd.pay 
FROM users_data AS u 
LEFT JOIN 
     winners_data wd 
ON  (wd.nid, wd.uid) = (u.nid, u.uid) 
JOIN dp_node dn 
ON  dn.nid = u.nid 
     AND dn.type IN ('event', 'new_event') 
WHERE u.uid = ".$val." 
     AND EXISTS 
     (
     SELECT NULL 
     FROM tournament_event te 
     WHERE te.nid = u.nid 
       AND type_value IN ('A', 'B', 'C') 
       AND dn.type = 'event' 
     UNION ALL 
     SELECT NULL 
     FROM user_tournament_event te 
     WHERE te.nid = u.nid 
       AND type_0_value IN ('X', 'Y') 
       AND dn.type = 'new_event' 

     ) 
ORDER BY 
     u.nid ASC 

내가 dp_node에서 OUTER JOIN를 제거하여 원래 쿼리는 WHERE 절에 dp_node 필드에 비 NULL 조건을 요구하기 때문에, 그래서 LEFT JOIN 여기에 쓸모가 없다.

다음 인덱스 만들기 : 읽기

users_data (uid, nid) 
winners_data (uid, nid) 
dp_node (nid, event_type) 
tournament_event (nid, type_value) 
user_tournament_event (nid, type_0_value) 
+1

젠장, 너 Quassnoi, 너는 빠르다. –

+1

'@ Leonel' : 너는 잠잠 해, 너 잃어! – Quassnoi

+0

@Lionel : 당신은 쉘 스크립트를 모티프 화하고 있습니다. –

0

이 해당 될 수도 있지만 쉽게 : "이벤트의 어떤 종류의"중요한 하나 인 경우

WITH NIDs(type_value,nid) AS (
    SELECT 'event', nid FROM tournament_event 
    WHERE type_value IN ('A','B','C') 
    UNION ALL 
    SELECT 'new_event', nid FROM user_tournament_event 
    WHERE type_value IN ('X','Y') 
) 

SELECT 
    u.uid, 
    u.username, 
    u.nid, 
    wd.pay 
FROM users_data AS u JOIN NIDs AS n 
ON n.nid = u.nid 
AND n.type_value = u."type" 
LEFT JOIN winners_data AS wd 
ON u.nid=wd.nid AND u.uid=wd.uid 
LEFT JOIN dp_node AS dn 
ON u.nid = dn.nid 
WHERE u.uid=".$val." 
ORDER BY nid ASC 

, 당신은 더 나을 것 하나의 테이블을 사용하여 하나 또는 두 개의 열을보고 결정할 수 있습니다. 이 정보를 가지고있는 두 개의 테이블 (tournament_event 및 user_tournament_event)이있는 것 같습니다. 예를 들어,이 쿼리의 NID 표현식 에서처럼 정보를 저장할 수 있습니다. 2009-08-22에

추가 :

열팽창 계수가 파생 테이블로 표현 함께 여기에 같은 쿼리가,이다 :이 스타일 (폐쇄을 모두 본 적이

SELECT 
    u.uid, 
    u.username, 
    u.nid, 
    wd.pay 
FROM users_data AS u JOIN (
    SELECT 'event', nid FROM tournament_event 
    WHERE type_value IN ('A','B','C') 
    UNION ALL 
    SELECT 'new_event', nid FROM user_tournament_event 
    WHERE type_value IN ('X','Y') 
) AS n(type_value,nid) 
ON n.nid = u.nid 
AND n.type_value = u."type" 
LEFT JOIN winners_data AS wd 
ON u.nid=wd.nid AND u.uid=wd.uid 
LEFT JOIN dp_node AS dn 
ON u.nid = dn.nid 
WHERE u.uid=".$val." 
ORDER BY nid ASC 
+1

FWIW는 MySQL이 CTE를 지원하지 않습니다. –

+0

@Bill : CTE는 파생 테이블로 다시 작성할 수 있기 때문에 CTE 지원은 문제가되지 않습니다. 다시 작성하여 답을 작성하겠습니다. 그러나 CTE를 그대로두면 사람들이 쉽게 읽을 수 있습니다. 그리고 언젠가는 MySQL이 잠시 ANSI/ISO 표준의 일부가 되었기 때문에 언젠가 MySQL을 지원할 것입니다. –

0

한 줄 끝의 괄호) 사람들이 어떻게 그것을 이해할 수 있는지 궁금해 할 것입니다. 누군가가 이전에 재 형식화 된 버전을 묻습니다.