Postgresql / PPAS/Query tuning

[hierarchy] query tuning

원샷원따봉 2022. 9. 15. 16:36

 

결과
 AS-IS
실행 완료. 총 쿼리 실행시간: 6 secs 294 msec. 15 로우가 영향받았음.
TO-BE
 
실행 완료. 총 쿼리 실행시간: 211 msec. 15 로우가 영향받았음.

 

- AS-IS PLAN

 
-  노드 별 병목 구간

 

 

- TO-BE PLAN

-  노드 별 병목 구간

 

 

- 원본 쿼리

WITH
	    TMP_QD_POLICY AS
         (  
    		SELECT '010101' AS TOT_GENRE
    	 UNION ALL 
    		SELECT '010103' AS TOT_GENRE
    	 UNION ALL 
    		SELECT '010107' AS TOT_GENRE
    	 UNION ALL 
    		SELECT '010117' AS TOT_GENRE
    	 UNION ALL 
    		SELECT '010130' AS TOT_GENRE
    	 UNION ALL 
    		SELECT '010131' AS TOT_GENRE
    	 UNION ALL 
    		SELECT '010132' AS TOT_GENRE
    	 UNION ALL 
    		SELECT '010201' AS TOT_GENRE
    	 UNION ALL 
    		SELECT '010202' AS TOT_GENRE
    	 UNION ALL 
    		SELECT '010203' AS TOT_GENRE
    	 UNION ALL 
    		SELECT '010204' AS TOT_GENRE
    	 UNION ALL 
    		SELECT '010207' AS TOT_GENRE
    	 UNION ALL 
    		SELECT '010217' AS TOT_GENRE
    	 UNION ALL 
    		SELECT '010301' AS TOT_GENRE
    	 UNION ALL 
    		SELECT '010302' AS TOT_GENRE
    	 UNION ALL 
    		SELECT '010303' AS TOT_GENRE
    	 UNION ALL 
    		SELECT '010307' AS TOT_GENRE
    	 UNION ALL 
    		SELECT '010317' AS TOT_GENRE
    	 UNION ALL 
    		SELECT '010402' AS TOT_GENRE
    	 UNION ALL 
    		SELECT '070201' AS TOT_GENRE
    	 ) 
    	 
	    ,TMP_QD_EXCEPT AS
         (  
    		SELECT 
    			'010101' AS EX_GENRE_SMALL
    			, '85118001' AS EX_SERIES
    	 UNION ALL 
    		SELECT 
    			'010107' AS EX_GENRE_SMALL
    			, '85104101' AS EX_SERIES
    	 UNION ALL 
    		SELECT 
    			'010117' AS EX_GENRE_SMALL
    			, '0126146601' AS EX_SERIES
    	 UNION ALL 
    		SELECT 
    			'010201' AS EX_GENRE_SMALL
    			, '11518201' AS EX_SERIES
    	 UNION ALL 
    		SELECT 
    			'010201' AS EX_GENRE_SMALL
    			, '13111201' AS EX_SERIES
    	 UNION ALL 
    		SELECT 
    			'010201' AS EX_GENRE_SMALL
    			, '6301301' AS EX_SERIES
    	 UNION ALL 
    		SELECT 
    			'010201' AS EX_GENRE_SMALL
    			, '6720101' AS EX_SERIES
    	 UNION ALL 
    		SELECT 
    			'010202' AS EX_GENRE_SMALL
    			, '6265401' AS EX_SERIES
    	 UNION ALL 
    		SELECT 
    			'010203' AS EX_GENRE_SMALL
    			, '42305301' AS EX_SERIES
    	 UNION ALL 
    		SELECT 
    			'010203' AS EX_GENRE_SMALL
    			, '7149801' AS EX_SERIES
    	 UNION ALL 
    		SELECT 
    			'010205' AS EX_GENRE_SMALL
    			, '6438701' AS EX_SERIES
    	 UNION ALL 
    		SELECT 
    			'010205' AS EX_GENRE_SMALL
    			, '83019801' AS EX_SERIES
    	 UNION ALL 
    		SELECT 
    			'010217' AS EX_GENRE_SMALL
    			, '0093008801' AS EX_SERIES
    	 UNION ALL 
    		SELECT 
    			'010217' AS EX_GENRE_SMALL
    			, '0094448401' AS EX_SERIES
    	 UNION ALL 
    		SELECT 
    			'010217' AS EX_GENRE_SMALL
    			, '0095144901' AS EX_SERIES
    	 UNION ALL 
    		SELECT 
    			'010217' AS EX_GENRE_SMALL
    			, '0126146801' AS EX_SERIES
    	 UNION ALL 
    		SELECT 
    			'010217' AS EX_GENRE_SMALL
    			, '0127023201' AS EX_SERIES
    	 UNION ALL 
    		SELECT 
    			'010217' AS EX_GENRE_SMALL
    			, '42389401' AS EX_SERIES
    	 UNION ALL 
    		SELECT 
    			'010217' AS EX_GENRE_SMALL
    			, '42485201' AS EX_SERIES
    	 UNION ALL 
    		SELECT 
    			'010217' AS EX_GENRE_SMALL
    			, '72010501' AS EX_SERIES
    	 UNION ALL 
    		SELECT 
    			'010217' AS EX_GENRE_SMALL
    			, '72011201' AS EX_SERIES
    	 UNION ALL 
    		SELECT 
    			'010217' AS EX_GENRE_SMALL
    			, '82004801' AS EX_SERIES
    	 UNION ALL 
    		SELECT 
    			'010301' AS EX_GENRE_SMALL
    			, '42601201' AS EX_SERIES
    	 UNION ALL 
    		SELECT 
    			'010301' AS EX_GENRE_SMALL
    			, '85135701' AS EX_SERIES
    	 UNION ALL 
    		SELECT 
    			'010303' AS EX_GENRE_SMALL
    			, '12817901' AS EX_SERIES
    	 UNION ALL 
    		SELECT 
    			'010317' AS EX_GENRE_SMALL
    			, '11573801' AS EX_SERIES
    	 ) 
    	 
		 
		 
		 
		 
	    SELECT /*genre.base.genreQdExcptInsertData*/
	    	TOTAL_CNT, RNUM, SERIES_ID_IMCS, SERIES_NAME, GENRE1, GENRE2, GENRE3,
	    	GENRE_NAME, GENRE_NAME2, GENRE_NAME3
	    FROM
	    
		
		
		
		(
	        SELECT
	            COUNT(A.SERIES_ID_IMCS) OVER() AS TOTAL_CNT,
	            A.RNUM, A.SERIES_ID_IMCS, A.SERIES_NAME, A.GENRE1, A.GENRE2, A.GENRE3,
        		A.GENRE_NAME, A.GENRE_NAME2, A.GENRE_NAME3
	        FROM
	    
			
			
			(
	        	SELECT ROW_NUMBER() OVER (ORDER BY GEN.SERIES_ID_IMCS DESC) RNUM,
	        		GEN.SERIES_ID_IMCS, MAX(GEN.SERIES_NAME) SERIES_NAME,
	        		GEN.GENRE1, GEN.GENRE2, GEN.GENRE3, 
	        		GEN.GENRE_NAME, GEN.GENRE_NAME2, GEN.GENRE_NAME3
			    FROM TMP_QD_POLICY TMP_QD, TMP_QD_EXCEPT TMP_EX,
			       	( 
			        	SELECT
			                GEN.SERIES_ID_IMCS, GEN.SERIES_NAME,
				             
				              CASE
				                WHEN LENGTH(GENRE_CD) >= 2 
				                THEN SUBSTR(GENRE_CD, 1,2)
				              END AS GENRE1,
				              CASE
				                WHEN LENGTH(GENRE_CD) >= 4
				                THEN SUBSTR(GENRE_CD, 1,4)
				              END AS GENRE2,
				              CASE
				                WHEN LENGTH(GENRE_CD) = 6
				                THEN GENRE_CD
				              END AS GENRE3,
				             
			                GEN.GENRE_NAME, 
			                GEN.GENRE_NAME2, 
			                GEN.GENRE_NAME3
			        	FROM
					  (
			                SELECT
					                SMAP.ALBUM_GROUP_ID AS SERIES_ID_IMCS, SER_MST.ALBUM_GROUP_NM AS SERIES_NAME,
					                ASB.GENRE_LARGE GENRE_NAME, 
					                ASB.GENRE_MID GENRE_NAME2, ASB.GENRE_SMALL GENRE_NAME3,
			                        (
									SELECT GENRE_CD
									FROM (
										WITH RECURSIVE CODE_LIST(GENRE_CD, GENRE_PARENT_CD, LEVEL, PATH, CYCLE) AS (
											SELECT GENRE_CD
												, GENRE_PARENT_CD
												, 1
												, ARRAY[GENRE_NAME::TEXT]
												, false
											FROM imcsuser.PT_CD_GENRE_CD
											WHERE GENRE_TYPE = 'L'
											UNION ALL
											SELECT A.GENRE_CD
												, A.GENRE_PARENT_CD
												, B.LEVEL + 1
												, B.PATH || A.GENRE_NAME::TEXT
												, A.GENRE_CD = ANY (B.PATH)
											FROM imcsuser.PT_CD_GENRE_CD A
												, CODE_LIST B
											WHERE A.GENRE_PARENT_CD = B.GENRE_CD
											AND NOT CYCLE
										)
										SELECT GENRE_CD
											, ARRAY_TO_STRING(PATH, ';') AS GENRE
											, LEVEL
										FROM CODE_LIST
										) A
									WHERE GENRE = COALESCE(GENRE_LARGE, '')
									                  || CASE WHEN NULLIF(GENRE_MID,'') IS NULL THEN '' ELSE ';' || GENRE_MID END
									                  || CASE WHEN NULLIF(GENRE_SMALL,'') IS NULL THEN '' ELSE ';' || GENRE_SMALL END
			                        )  GENRE_CD
					               
					        FROM imcsuser.PT_LA_ALBUM_INFO AI
					           , imcsuser.PT_LA_ALBUM_SUB ASB
					           , imcsuser.PT_LA_ALBUM_GROUP SER_MST
					           , imcsuser.PT_LA_ALBUM_RELATION SMAP
					        WHERE 1 = 1
					         
					             
					             
					                AND SER_MST.ALBUM_GROUP_NM LIKE ('%'||'시리즈'||'%')
					             
					         
					        AND SMAP.ALBUM_ID = AI.ALBUM_ID
					        AND AI.ALBUM_ID = ASB.ALBUM_ID
					        AND SMAP.ALBUM_GROUP_ID = SER_MST.ALBUM_GROUP_ID   
					        AND SMAP.GROUP_TYPE 	= SER_MST.GROUP_TYPE   
					        AND SER_MST.GROUP_TYPE 	= 'S'  
						)GEN
					)GEN
			        WHERE 1 = 1
			        AND GEN.GENRE3 = TMP_QD.TOT_GENRE
					AND GEN.GENRE3||GEN.SERIES_ID_IMCS NOT IN (TMP_EX.EX_GENRE_SMALL||TMP_EX.EX_SERIES)
			        GROUP BY GEN.SERIES_ID_IMCS, GEN.GENRE1, GEN.GENRE2, GEN.GENRE3, 
			        		GEN.GENRE_NAME, GEN.GENRE_NAME2, GEN.GENRE_NAME3
			        ORDER BY GEN.SERIES_ID_IMCS DESC
	        ) A
	    )B
	    WHERE B.RNUM BETWEEN 0+1 AND 0 + 50

 

- 튜닝 쿼리

--explain (analyze on, buffers on, costs on, verbose on, settings on, timing on )

with recursive
CODE_LIST(GENRE_CD, GENRE_PARENT_CD, LEVEL, PATH, CYCLE) AS
       (
       SELECT GENRE_CD
                                    , GENRE_PARENT_CD
                                    , 1
                                    , ARRAY[GENRE_NAME::TEXT]
                                    , false
                                 FROM imcsuser.PT_CD_GENRE_CD
                                 WHERE GENRE_TYPE = 'L'
                                 UNION ALL
                                 SELECT A.GENRE_CD
                                    , A.GENRE_PARENT_CD
                                    , B.LEVEL + 1
                                    , B.PATH || A.GENRE_NAME::TEXT
                                    , A.GENRE_CD = ANY (B.PATH)
                                 FROM imcsuser.PT_CD_GENRE_CD A
                                    , CODE_LIST B
                                 WHERE A.GENRE_PARENT_CD = B.GENRE_CD
                                 AND NOT CYCLE 
       ) ,
	  


       TMP_QD_POLICY AS
         (  
          SELECT '010101' AS TOT_GENRE
        UNION ALL 
          SELECT '010103' AS TOT_GENRE
        UNION ALL 
          SELECT '010107' AS TOT_GENRE
        UNION ALL 
          SELECT '010117' AS TOT_GENRE
        UNION ALL 
          SELECT '010130' AS TOT_GENRE
        UNION ALL 
          SELECT '010131' AS TOT_GENRE
        UNION ALL 
          SELECT '010132' AS TOT_GENRE
        UNION ALL 
          SELECT '010201' AS TOT_GENRE
        UNION ALL 
          SELECT '010202' AS TOT_GENRE
        UNION ALL 
          SELECT '010203' AS TOT_GENRE
        UNION ALL 
          SELECT '010204' AS TOT_GENRE
        UNION ALL 
          SELECT '010207' AS TOT_GENRE
        UNION ALL 
          SELECT '010217' AS TOT_GENRE
        UNION ALL 
          SELECT '010301' AS TOT_GENRE
        UNION ALL 
          SELECT '010302' AS TOT_GENRE
        UNION ALL 
          SELECT '010303' AS TOT_GENRE
        UNION ALL 
          SELECT '010307' AS TOT_GENRE
        UNION ALL 
          SELECT '010317' AS TOT_GENRE
        UNION ALL 
          SELECT '010402' AS TOT_GENRE
        UNION ALL 
          SELECT '070201' AS TOT_GENRE
        ) 
        
       ,TMP_QD_EXCEPT AS
         (  
          SELECT 
             '010101' AS EX_GENRE_SMALL
             , '85118001' AS EX_SERIES
        UNION ALL 
          SELECT 
             '010107' AS EX_GENRE_SMALL
             , '85104101' AS EX_SERIES
        UNION ALL 
          SELECT 
             '010117' AS EX_GENRE_SMALL
             , '0126146601' AS EX_SERIES
        UNION ALL 
          SELECT 
             '010201' AS EX_GENRE_SMALL
             , '11518201' AS EX_SERIES
        UNION ALL 
          SELECT 
             '010201' AS EX_GENRE_SMALL
             , '13111201' AS EX_SERIES
        UNION ALL 
          SELECT 
             '010201' AS EX_GENRE_SMALL
             , '6301301' AS EX_SERIES
        UNION ALL 
          SELECT 
             '010201' AS EX_GENRE_SMALL
             , '6720101' AS EX_SERIES
        UNION ALL 
          SELECT 
             '010202' AS EX_GENRE_SMALL
             , '6265401' AS EX_SERIES
        UNION ALL 
          SELECT 
             '010203' AS EX_GENRE_SMALL
             , '42305301' AS EX_SERIES
        UNION ALL 
          SELECT 
             '010203' AS EX_GENRE_SMALL
             , '7149801' AS EX_SERIES
        UNION ALL 
          SELECT 
             '010205' AS EX_GENRE_SMALL
             , '6438701' AS EX_SERIES
        UNION ALL 
          SELECT 
             '010205' AS EX_GENRE_SMALL
             , '83019801' AS EX_SERIES
        UNION ALL 
          SELECT 
             '010217' AS EX_GENRE_SMALL
             , '0093008801' AS EX_SERIES
        UNION ALL 
          SELECT 
             '010217' AS EX_GENRE_SMALL
             , '0094448401' AS EX_SERIES
        UNION ALL 
          SELECT 
             '010217' AS EX_GENRE_SMALL
             , '0095144901' AS EX_SERIES
        UNION ALL 
          SELECT 
             '010217' AS EX_GENRE_SMALL
             , '0126146801' AS EX_SERIES
        UNION ALL 
          SELECT 
             '010217' AS EX_GENRE_SMALL
             , '0127023201' AS EX_SERIES
        UNION ALL 
          SELECT 
             '010217' AS EX_GENRE_SMALL
             , '42389401' AS EX_SERIES
        UNION ALL 
          SELECT 
             '010217' AS EX_GENRE_SMALL
             , '42485201' AS EX_SERIES
        UNION ALL 
          SELECT 
             '010217' AS EX_GENRE_SMALL
             , '72010501' AS EX_SERIES
        UNION ALL 
          SELECT 
             '010217' AS EX_GENRE_SMALL
             , '72011201' AS EX_SERIES
        UNION ALL 
          SELECT 
             '010217' AS EX_GENRE_SMALL
             , '82004801' AS EX_SERIES
        UNION ALL 
          SELECT 
             '010301' AS EX_GENRE_SMALL
             , '42601201' AS EX_SERIES
        UNION ALL 
          SELECT 
             '010301' AS EX_GENRE_SMALL
             , '85135701' AS EX_SERIES
        UNION ALL 
          SELECT 
             '010303' AS EX_GENRE_SMALL
             , '12817901' AS EX_SERIES
        UNION ALL 
          SELECT 
             '010317' AS EX_GENRE_SMALL
             , '11573801' AS EX_SERIES
        ) 
        
 
       
       
       
       SELECT /*genre.base.genreQdExcptInsertData*/
          TOTAL_CNT, RNUM, SERIES_ID_IMCS, SERIES_NAME, GENRE1, GENRE2, GENRE3,
          GENRE_NAME, GENRE_NAME2, GENRE_NAME3
       FROM
       
      
      
      
      (
           SELECT
               COUNT(A.SERIES_ID_IMCS) OVER() AS TOTAL_CNT,
               A.RNUM, A.SERIES_ID_IMCS, A.SERIES_NAME, A.GENRE1, A.GENRE2, A.GENRE3,
              A.GENRE_NAME, A.GENRE_NAME2, A.GENRE_NAME3
           FROM
       
         
         
         (
              SELECT ROW_NUMBER() OVER (ORDER BY GEN.SERIES_ID_IMCS DESC) RNUM,
                 GEN.SERIES_ID_IMCS, MAX(GEN.SERIES_NAME) SERIES_NAME,
                 GEN.GENRE1, GEN.GENRE2, GEN.GENRE3, 
                 GEN.GENRE_NAME, GEN.GENRE_NAME2, GEN.GENRE_NAME3
             FROM TMP_QD_POLICY TMP_QD, TMP_QD_EXCEPT TMP_EX,
                   ( 
                    SELECT
                         GEN.SERIES_ID_IMCS, GEN.SERIES_NAME,
                         
                          CASE
                            WHEN LENGTH(GENRE_CD) >= 2 
                            THEN SUBSTR(GENRE_CD, 1,2)
                          END AS GENRE1,
                          CASE
                            WHEN LENGTH(GENRE_CD) >= 4
                            THEN SUBSTR(GENRE_CD, 1,4)
                          END AS GENRE2,
                          CASE
                            WHEN LENGTH(GENRE_CD) = 6
                            THEN GENRE_CD
                          END AS GENRE3,
                         
                         GEN.GENRE_NAME, 
                         GEN.GENRE_NAME2, 
                         GEN.GENRE_NAME3
                    FROM
                 (
                         SELECT
                               SMAP.ALBUM_GROUP_ID AS SERIES_ID_IMCS, SER_MST.ALBUM_GROUP_NM AS SERIES_NAME,
                               ASB.GENRE_LARGE GENRE_NAME, 
                               ASB.GENRE_MID GENRE_NAME2, ASB.GENRE_SMALL GENRE_NAME3,
                                 /*(
                           SELECT GENRE_CD
                           FROM (
                              WITH RECURSIVE CODE_LIST(GENRE_CD, GENRE_PARENT_CD, LEVEL, PATH, CYCLE) AS (
                                 SELECT GENRE_CD
                                    , GENRE_PARENT_CD
                                    , 1
                                    , ARRAY[GENRE_NAME::TEXT]
                                    , false
                                 FROM imcsuser.PT_CD_GENRE_CD
                                 WHERE GENRE_TYPE = 'L'
                                 UNION ALL
                                 SELECT A.GENRE_CD
                                    , A.GENRE_PARENT_CD
                                    , B.LEVEL + 1
                                    , B.PATH || A.GENRE_NAME::TEXT
                                    , A.GENRE_CD = ANY (B.PATH)
                                 FROM imcsuser.PT_CD_GENRE_CD A
                                    , CODE_LIST B
                                 WHERE A.GENRE_PARENT_CD = B.GENRE_CD
                                 AND NOT CYCLE
                              )
                              SELECT GENRE_CD
                                 , ARRAY_TO_STRING(PATH, ';') AS GENRE
                                 , LEVEL
                              FROM CODE_LIST
                              ) A
                           WHERE GENRE = COALESCE(GENRE_LARGE, '')
                                             || CASE WHEN NULLIF(GENRE_MID,'') IS NULL THEN '' ELSE ';' || GENRE_MID END
                                             || CASE WHEN NULLIF(GENRE_SMALL,'') IS NULL THEN '' ELSE ';' || GENRE_SMALL END
                                 )  GENRE_CD*/
                           CODE.GENRE_CD
                              
                       FROM imcsuser.PT_LA_ALBUM_INFO AI
                          , imcsuser.PT_LA_ALBUM_SUB ASB
                          , imcsuser.PT_LA_ALBUM_GROUP SER_MST
                          , imcsuser.PT_LA_ALBUM_RELATION SMAP
                        ,CODE_LIST CODE
                       WHERE 1 = 1
                     /*추가 START */
                         AND ARRAY_TO_STRING(PATH, ';') =COALESCE(ASB.GENRE_LARGE, '')
                                             || CASE WHEN NULLIF(ASB.GENRE_MID,'') IS NULL THEN '' ELSE ';' || ASB.GENRE_MID END
                                             || CASE WHEN NULLIF(ASB.GENRE_SMALL,'') IS NULL THEN '' ELSE ';' || ASB.GENRE_SMALL END
                       /*추가 END */     
                            
                               AND SER_MST.ALBUM_GROUP_NM LIKE ('%'||'시리즈'||'%')
                            
                        
                       AND SMAP.ALBUM_ID = AI.ALBUM_ID
                       AND AI.ALBUM_ID = ASB.ALBUM_ID
                       AND SMAP.ALBUM_GROUP_ID = SER_MST.ALBUM_GROUP_ID   
                       AND SMAP.GROUP_TYPE    = SER_MST.GROUP_TYPE   
                       AND SER_MST.GROUP_TYPE    = 'S'  
                  )GEN
               )GEN
                 WHERE 1 = 1
                 AND GEN.GENRE3 = TMP_QD.TOT_GENRE
               AND GEN.GENRE3||GEN.SERIES_ID_IMCS NOT IN (TMP_EX.EX_GENRE_SMALL||TMP_EX.EX_SERIES)
                 GROUP BY GEN.SERIES_ID_IMCS, GEN.GENRE1, GEN.GENRE2, GEN.GENRE3, 
                       GEN.GENRE_NAME, GEN.GENRE_NAME2, GEN.GENRE_NAME3
                 ORDER BY GEN.SERIES_ID_IMCS DESC
           ) A
       )B
       WHERE B.RNUM BETWEEN 0+1 AND 0 + 50