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
'programing' 카테고리의 다른 글
(ActiveXObject 없이) JavaScript로 Excel 파일을 읽는 방법 (0) | 2023.11.01 |
---|---|
데이터를 삽입했지만 jquery는 여전히 오류를 반환합니다. (0) | 2023.11.01 |
Lazy div 배경 이미지를 로드하는 방법 (0) | 2023.11.01 |
ARC를 사용하고 iOS 4.0을 대상으로 할 때 약한 참조를 대체하려면 어떻게 해야 합니까? (0) | 2023.11.01 |
다른 포트에 도커 mysql (0) | 2023.11.01 |