2011-09-08 6 views
2

Venues 테이블에 장소 목록이 있고 Locations 테이블에 도시/상태 목록이 있습니다. 개최지는 SOYID라고하는 조직 고유의 지역 번호와 관련됩니다. SOYID는 지리적 영역으로 구성됩니다. Locations 테이블의 각 행에는 City, State 및 해당 SOYID가 있습니다. 일부 Venues 행에는 SOYID가 있고 다른 행에는 SOYID가 없습니다. 그렇지 않은 사람들은 도시와 주에 대한 SOYID를 찾아야합니다. 나는 특정 SOYID의 장소 만 선택하려고합니다.작은 MySQL 조인 쿼리 최적화

이 쿼리는 작동하지만로드하는 데 몇 초가 걸립니다. 쿼리를 올바르게 작성하고 있다고 생각하지 않습니다. 현재 Venues에는 약 140 개의 행이 있고 Locations에는 40,000 개의 행이 있습니다.

$sql = "SELECT DISTINCT a.VenueID, a.Name, a.PhotoID, a.City, a.StateAbbr 
      FROM Venues AS a LEFT JOIN Locations AS c ON a.City = c.city 
      WHERE a.SOYID = '" . mysql_real_escape_string($SOYID) . "' 
      OR ((c.city = a.City) AND (c.state = a.StateAbbr) AND (c.SOYID = '" . mysql_real_escape_string($SOYID) . "')) 
      ORDER BY a.Name ASC"; 

답변

2

내부 가입을 같은 행동에 참여하면 WHERE 절, 당신의 힘에 (특정 경우에 c.statec.SOYID) 왼쪽 조인 된 테이블에서 열을 참조 할 때마다.

"SELECT DISTINCT a.VenueID, a.Name, a.PhotoID, a.City, a.StateAbbr 
    FROM Venues AS a 
     LEFT JOIN Locations AS c 
      ON a.City = c.city 
       AND a.StateAbbr = c.state 
       AND c.SOYID = '" . mysql_real_escape_string($SOYID) . "' 
    WHERE a.SOYID = '" . mysql_real_escape_string($SOYID) . "' 
     OR c.SOYID IS NOT NULL /* LEFT JOIN found a matching row */ 
    ORDER BY a.Name ASC" 

편집 : 대신, 이러한 테스트를 조인 조건의 일부를 만들어 의견을 바탕으로,이 버전은 당신이 DISTINCT 요구 사항을 제거 할 수 있도록해야합니다

"SELECT a.VenueID, a.Name, a.PhotoID, a.City, a.StateAbbr 
    FROM Venues AS a 
    WHERE a.SOYID = '" . mysql_real_escape_string($SOYID) . "' 
     OR EXISTS(SELECT NULL 
         FROM Locations AS c 
         WHERE a.City = c.city 
          AND a.StateAbbr = c.state 
          AND c.SOYID = '" . mysql_real_escape_string($SOYID) . "') 
    ORDER BY a.Name ASC" 
+0

나는 그가 삭제할 수 있습니다 추측을' 지금은 그렇지 않습니까? 아니면'DISTINCT' 대신'GROUP BY a.VenuID'를 사용하십시오. –

+0

@ypercube : 예, 아마도 DISTINCT를 삭제하는 것이 안전하다고 생각합니다. –

+0

뚜렷한 부분을 삭제하면 여전히 반복 행이 표시되므로 아니요, 여전히 고유 한 부분을 유지해야합니다. 감사! –