안녕하세요.
아래와 같은 쿼리가 있습니다. 상품테이블의 카테고리를 보여주려고 join을 하고 있는데 제 생각엔 모델링부터가 잘못된 것 같습니다.
SELECT G.* , C.T1_CTG_NM , C.T2_CTG_NM , C.T3_CTG_NM , CONCAT_WS(',',T.T1_CTG_NO,T.T2_CTG_NO,T.T3_CTG_NO,T.T4_CTG_NO ) AS CTG_NO_ARR FROM ( SELECT T1.CTG_NO AS T1_CTG_NO , T1.CTG_NM AS T1_CTG_NM , T2.CTG_NO AS T2_CTG_NO , T2.CTG_NM AS T2_CTG_NM , T3.CTG_NO AS T3_CTG_NO , T3.CTG_NM AS T3_CTG_NM , T4.CTG_NO AS T4_CTG_NO , T4.CTG_NM AS T4_CTG_NM FROM CTG T1 LEFT OUTER JOIN CTG T2 ON T2.UP_CTG_NO = T1.CTG_NO LEFT OUTER JOIN CTG T3 ON T3.UP_CTG_NO = T2.CTG_NO LEFT OUTER JOIN CTG T4 ON T4.UP_CTG_NO = T3.CTG_NO ) C, ( SELECT PR.* , CTG.CTG_NO , CTG.CTG_LVL FROM PRODUCT PR LEFT OUTER JOIN PRODUCT_CTG PRC ON PRC.GOODS_NO = PR.GOODS_NO AND PRC.DLGT_CTG_YN = 'Y' AND IFNULL(PRC.DEL_YN,'N') = 'N' LEFT OUTER JOIN CTG CTG ON CTG.CTG_NO = PRC.CTG_NO ) G WHERE G.CTG_NO=CASE G.CTG_LVL WHEN 1 THEN T1_CTG_NO WHEN 2 THEN T2_CTG_NO WHEN 3 THEN T3_CTG_NO WHEN 4 THEN T4_CTG_NO ELSE '' END
C라는 인라인뷰는 0.041초가 나오고 (2499 rows)
G라는 인라인뷰는 0.32초가 나옵니다. (58636 rows)
여기까진 문제 없습니다.
그런데 둘을 JOIN하면 25초라는 수치가 나옵니다. 참고로 페이징처리는 할 수 없습니다. 전체 row가 다 나와야해서요.
Hash Join이 있으면 속도가 나올것 같지만 아쉽게 MySQL이여서... 대신 Join Buffer와 Block Nested Join 기법을 사용하여 JOIN을 하는데 속도가 나지 않습니다. 일반 NL Join을 하면 28초 정도 걸립니다.
좋은 방안이 있을까요.??
감사합니다.
SELECT pr.* , c1.ctg_no , c1.ctg_nm , c1.ctg_lvl , CASE c1.ctg_lvl WHEN 1 THEN c1.ctg_nm WHEN 2 THEN c2.ctg_nm WHEN 3 THEN c3.ctg_nm WHEN 4 THEN c4.ctg_nm END ctg_nm_1 , CASE c1.ctg_lvl WHEN 2 THEN c1.ctg_nm WHEN 3 THEN c2.ctg_nm WHEN 4 THEN c3.ctg_nm END ctg_nm_2 , CASE c1.ctg_lvl WHEN 3 THEN c1.ctg_nm WHEN 4 THEN c2.ctg_nm END ctg_nm_3 , CASE c1.ctg_lvl WHEN 4 THEN c1.ctg_nm END ctg_nm_4 , CONCAT_WS(',', c4.ctg_no, c3.ctg_no, c2.ctg_no, c1.ctg_no) ctg_no_arr , CONCAT_WS(',', c4.ctg_nm, c3.ctg_nm, c2.ctg_nm, c1.ctg_nm) ctg_nm_arr FROM product pr LEFT OUTER JOIN product_ctg prc ON prc.goods_no = pr.goods_no AND prc.dlgt_ctg_yn = 'Y' AND IFNULL(prc.del_yn, 'N') = 'N' LEFT OUTER JOIN ctg c1 ON prc.ctg_no = c1.ctg_no LEFT OUTER JOIN ctg c2 ON c1.up_ctg_no = c2.ctg_no LEFT OUTER JOIN ctg c3 ON c2.up_ctg_no = c3.ctg_no LEFT OUTER JOIN ctg c4 ON c3.up_ctg_no = c4.ctg_no ;