2017-11-27 6 views
1

JOIN을 사용하여 아래에 쿼리를 작성하는 더 좋은 방법이 있습니까?WHERE 또는 ... 대신 하위 쿼리를 사용하십시오. 하위 쿼리

SELECT 
    t1.id 
FROM 
    t1 
WHERE 
    (
     t1.date1 >= (UTC_TIMESTAMP() + INTERVAL - 20 Hour) 
    OR t1.date2 >= (UTC_TIMESTAMP() + INTERVAL - 20 Hour) 
    OR t1.id2 IN (SELECT id FROM t2) 
    OR t1.id3 IN (SELECT id FROM t2) 
    OR t1.id4 IN (SELECT id FROM t2) 
    ); 

업데이트 : 만 날짜 2가 NULL

+0

조인해야합니까, 아니면 쿼리를 좀 더 우아하게 만들 수있는 방법을 찾고 있습니까? – Mureinik

+1

@Mureinik 예, 그것이 원래 의도입니다. 그러나 나는 그것이 우아하든 그렇지 않든 상관없이 실제로는 "더 나은"것을 의미합니다. – tatskie

답변

0

는 OR 작업은 아마 당신의 속도로 엉망으로 가고있는 대부분의 OR은 인덱스 성능을 떨어 뜨립니다. 이 가장 간결로 변환은 동등 조인

SELECT t1.id 
FROM t1 INNER JOIN t2 ON t2.id IN (t1.id2, t1.id3, t1.id4) 
WHERE t1.date1 >= (UTC_TIMESTAMP() + INTERVAL - 20 Hour) 
    OR t1.date2 >= (UTC_TIMESTAMP() + INTERVAL - 20 Hour) 
; 

IN이 논리적으로 OR입니다,하지만 난 더 최근의 MySQL 버전이 조금을 최적화 한 생각; 하지 않을 경우,이 성능 향상이있을 수 있습니다

SELECT t1.id 
FROM t1 
    LEFT JOIN t2 AS t2_2 ON t2_2.id = t1.id2 
    LEFT JOIN t2 AS t2_3 ON t2_3.id = t1.id3 
    LEFT JOIN t2 AS t2_4 ON t2_4.id = t1.id4 
WHERE (t1.date1 >= (UTC_TIMESTAMP() + INTERVAL - 20 Hour) 
     OR t1.date2 >= (UTC_TIMESTAMP() + INTERVAL - 20 Hour) 
    ) 
     AND (t2_2.id IS NOT NULL OR t2_3.id IS NOT NULL OR t2_4.id IS NOT NULL) 
; 

는 그것은 ID 필드에 또는의를 피할 수 있으므로 해당 필드에 색인을 활용할 수를; 하지만 JOIN은 3 배 정도이기 때문에 더 느리게 끝날 수 있습니다.

1

내가 여기 join을 사용하는 방법을 생각할 수 없다 할 수 있지만, 의도 쿼리가 더 우아하고 만드는 경우/또는 유지 관리가 용이, 의견에 암시 될 때, 당신이 할 수있는 몇 가지 일이 있습니다.

먼저 날짜 조건. 동일한 용어를 두 번 반복하는 대신, 날짜의 최대 값이 주어진 기간보다 크거나 같은지 확인하십시오. date1 또는 date2null이 될 수 없다고 가정하면됩니다.

둘째, ID 조건. 동일한 용어를 세 번 반복하는 대신 단일 exists 조건을 사용할 수 있습니다. 나는 그것을 확인 편리 MySQL 데이터베이스를 필요는 없지만, 기회는 실제로 당신의 원래 버전보다 빠르게 실행하고 단지 보이지 않는 것입니다 청소기 :

SELECT 
    t1.id 
FROM 
    t1 
WHERE 
    GREATEST(t1.date1, t1.date2) >= (UTC_TIMESTAMP() + INTERVAL - 20 Hour) 
    OR EXISTS (SELECT * FROM t2 WHERE id IN (t1.id2, t1.id3, t1.id4)); 
+0

'date1' 또는'date2'가 NULL 일 수 있으면 원본과 동일하지 않습니다. – spencer7593

+0

@ spencer7593 좋은 캐치! 내 대답에 명확한 설명을 추가했습니다. – Mureinik