programing

MySQL: 관계에 참여하지 않는 행 찾기

css3 2023. 11. 1. 22:31

MySQL: 관계에 참여하지 않는 행 찾기

저는 '영화'와 '사용자'라는 두 개의 테이블을 가지고 있습니다.이들 사이에는 사용자가 본 영화를 설명하는 n:m 관계가 있습니다.이것은 '본' 표와 함께 설명됩니다. 이제 저는 특정 사용자, 그가 보지 못한 모든 영화에 대해 알아보려고 합니다.현재 솔루션은 다음과 같습니다.

SELECT *
FROM movies 
WHERE movies.id NOT IN (
     SELECT seen.movie_id 
     FROM seen 
     WHERE seen.user_id=123
)

이것은 잘 작동하지만 확장이 잘 되지 않는 것 같습니다.이에 대한 더 나은 접근 방법이 있습니까?

보여준 하위 쿼리 방법을 사용하지 않고 이 쿼리를 수행하는 일반적인 방법은 다음과 같습니다.이는 조인 기반 솔루션을 보고 싶다는 @Godke의 요청을 만족시킬 수 있습니다.

SELECT * 
FROM movies m
 LEFT OUTER JOIN seen s
 ON (m.id = s.movie_id AND s.user_id = 123)
WHERE s.movie_id IS NULL;

그러나 대부분의 데이터베이스 브랜드에서 이 솔루션은 하위 쿼리 솔루션보다 성능이 떨어질 수 있습니다.두 쿼리를 모두 분석할 때는 EXPRESON을 사용하여 스키마와 데이터를 고려할 때 어떤 쿼리가 더 효과적인지 확인하는 것이 가장 좋습니다.

하위 쿼리 솔루션에 대한 또 다른 변화는 다음과 같습니다.

SELECT * 
FROM movies m
WHERE NOT EXISTS (SELECT * FROM seen s 
                  WHERE s.movie_id = m.id 
                    AND s.user_id=123);

이는 상관 관계가 있는 하위 쿼리로, 외부 쿼리의 모든 행에 대해 평가해야 합니다.일반적으로 비용이 많이 들고 원래 예제 쿼리가 더 좋습니다.반면 MySQL에서는 "NOT EXISTS" 종종 "보다 낫습니다.column NOT IN (...)"

다시 한 번 각 솔루션을 검정하고 결과를 비교하여 확실하게 확인해야 합니다.성능을 측정하지 않고 솔루션을 선택하는 것은 시간 낭비입니다.

쿼리가 작동할 뿐만 아니라 명시된 대로 문제에 대한 올바른 접근 방식입니다.문제에 접근할 수 있는 다른 방법을 찾을 수 있을까요?예를 들어, 큰 테이블의 경우에도 외부 선택에 대한 간단한 LIMIT는 매우 빠릅니다.

조인 테이블이 표시되어 있습니다. 예, 올바른 솔루션인 것 같습니다.동영상의 전체에서 SEEN(사용자의 경우)에 있는 동영상 ID 집합을 효과적으로 "추출"하여 해당 사용자에게 보이지 않는 동영상을 생성하는 것입니다.

이것은 "부정적인 조인"이라고 불리는데 안타깝게도 NOT IN 또는 NOT EXISMENT가 최선의 선택입니다.(INNER/OUTER/LEFT/RIGHT 조인과 유사한 네거티브 조인 구문을 보고 싶지만 ON 절이 뺄셈 문일 수 있습니다.)

@Bill은 하위 쿼리가 없는 솔루션이 효과가 있을 것입니다. 비록 Bill은 솔루션의 성능을 두 가지 방법으로 테스트하는 것이 좋습니다.나는 그 서브쿼리가 전체적으로 보이든 안 보이든 아니든.ID 인덱스(물론 전체 무비).ID 인덱스)는 두 가지 방식으로 평가됩니다. 즉, 최적화자가 이를 처리하는 방식에 따라 달라집니다.

DBMS가 비트맵 인덱스를 지원하는 경우 시도해 볼 수 있습니다.

언급URL : https://stackoverflow.com/questions/544094/mysql-finding-rows-that-dont-take-part-in-a-relationship