1:다 의 관계에서 테이블을 조합해서 보여줘야하는 경우가 있습니다.
이 때 조인보다는 서브쿼리를 이용하는게 성능상 좋다고 들었습니다.
1:1다 관계일 때 조인보다 서브쿼리가 성능상 좋은게 맞나요?
맞다면 왜 그런지 궁금합니다.
아래는 1명의 사람에 3개의 이미지가 저장된 1:다 경우입니다.
아래에 조인으로 되어 있는 쿼리를 서브쿼리형식으로 변환시키려면 어떻게 해야할까요 ㅜ.ㅜ
CREATE TABLE TABLE1 ( NAME CHAR(8), AGE TINYINT ) CREATE TABLE TABLE2 ( NAME CHAR(8), IMAGE VARCHAR(500) ) INSERT INTO TABLE1 VALUES ('김개똥', 19) INSERT INTO TABLE2 VALUES ('김개똥', 'ABCD.JPG'), ('김개똥', 'AAAA.GIF'), ('김개똥', 'AGFASD.JPG') SELECT A.NAME, A.AGE, B.IMAGE FROM TABLE1 AS A JOIN TABLE2 AS B
ON A.NAME = B.NAME
Comment 4
-
건우아빠
2013.09.26 12:38
-
흑흑
2013.09.26 12:53
답변 감사합니다.
혹시 서브쿼리 위치를 바꾼다면 (a테이블과 b테이블)
image 컬럼에 데이터가 여러개 있어서 쿼리값을 두개 이상반환해서 오류가 뜨는데요
이때는 어떻게 해결해야할까요
-
맨즈밤
2013.09.26 13:54
질문이 포괄적이라 간략하게 적어봅니다. 경험에 기반해서 적은거라 오류가 있을수도 있습니다....
자세한 설명은 민석님등 전문 DBA님들 께서 ..
우선 용어먼저 정리하셔야할듯 한데요.
SELECT 절에 오는 서브쿼리는 스칼라 서브쿼리라고 불리우고 , 함수호출처럼 결과 행수만큼
반복 호출되기에 성능이 느려질 경우가 대부분이라고 보시면 됩니다. 물론 경우에 따라 성능이 나아지는경우도 있긴 합니다만 일반적인 경우를 말씀드리는 거구요. 한로우의 한컬럼은 하나의 값만 표시되야하므로 스칼라 서브쿼리의 반환값은 당연히 하나여야 합니다.
또 중요한건 결과집합의 ROW 자체에는 영향을 미치지 않습니다. INNER 조인을 서브쿼리로 바꿀경우 결과자체가 틀려질수있습니다.
그다음 FROM 절에 오는 서브쿼리를 인라인뷰라고 합니다. 성능적으로는 집합을 먼저 줄여줌으로써 다음 조인이나 기타 연산의 부담을 줄여줄때 사용하면 효과가 좋습니다.
그리고 WHERE 절에 오는게 일반적으로 말하는 서브쿼리구요. 이때도 경우에 따라 느려질때와 빨라질때가 있습니다.
SELECT *
FROM TABLE1
WHERE NAME IN (SELECT NAME FROM TABLE2 WHERE IMAGE='ABCD.JPG' )
위와같은경우 TABLE1과 상관없이 서브쿼리가 먼저 독립적으로 실행된후 WHERE절에서 수행될수 있으므로
TABLE1에는 NAME ,TABLE2에는 IMAGE 에 인덱스가 있다면 효과가 있습니다.
SELECT *
FROM TABLE1
WHERE EXISTS (SELECT NAME FROM TABLE2 WHERE TABLE1.NAME=NAME AND IMAGE='ABCD.JPG' )
위와같은경우 TABLE1의 NAME 컬럼이 서브쿼리 안에 있는 상관하위질의는 서브쿼리먼저 수행될수 없는 구조입니다. 즉 TABLE1이 백만건이면 서브쿼리가 아무리 가벼워도 백만건이 실행될수밖에 없습니다.
주절주절 적었습니다만, 절대적인 기준은 없다고 생각합니다. 1:다 관계는 대부분 테이블에서 나타나는 구조인데,
그 모든 경우의 수가 조인이 낫다 , 서브쿼리가 낫다 할수 없을것 같습니다. 다만 조인은 해쉬조인,루프조인,머지조인등 옵티마이저
선택의 폭이 넓으므로 대부분은 조인이 나을것입니다. 하지만 가령 TABLE2의 데이터 100만건중 1000건만 NAME에 값이 있을경우
CASE문에서 값이 있을때만 스칼라서브쿼리를 타도록 할수도 있을겁니다. 또는 1:다 조인은 다 만큼의 로우가 생성되는 만큼
그로인해 다음 조인에 영향을 미치거나, 연산해야할 로우가 커질경우 역시나 스칼라서브쿼리나 함수를 사용할수도 있을겁니다.
또는 스칼라서브쿼리의 크기가 굉장히 작거나 특정 값만 집중적으로 읽는경우 메모리에서 계속 로드될가능성이 크므로 이경우도 조인대비 효과가 있을수도 있을겁니다.
다양한 각도로 분석해보시고 테스트해보시면 좋은 결과를 찾을수 있으리라 봅니다.
-
흑흑
2013.09.27 17:09
자세한 답변 감사합니다^^
SELECT B.NAME
, ( SELECT AGE FROM TABLE1 WHERE NAME = B.NAME ) NAME
, B.IMAGE
FROM TABLE2 AS B
1:다일 때는 서브쿼리가 성능이 좋다 보다는 좋은 경우도 있다가 맞지 않을까요..
설명의 민석님등 전문 DBA님들 께서 ..