优化具有多个子查询的Oracle SQL

时间:2014-07-28 21:08:00

标签: sql oracle optimization query-optimization

我有一个Oracle SQL查询,其中包含多个子查询。查询提供正确的数据,但执行需要15-20分钟。在阅读以下链接中的一些答案之后:

  1. https://dba.stackexchange.com/questions/19605/forcing-oracle-to-use-hash-join-for-a-subquery
  2. Optimize performance of sub-queries
  3. 我尝试使用GLOBAL TEMPORARY TABLE优化查询,但似乎我没有CREATE命令的权限。

    我想问一下,如果有人知道任何优化下面查询性能的工具或技术:

    此查询用于为每个校园和计划生成入场号码。

    SELECT DISTINCT STVCAMP_DESC "CAMPUS",
    STVDEGC_CODE || ' - ' ||STVDEGC_DESC "PROGRAMME",
    
    (SELECT COUNT(DISTINCT SARADAP_PIDM) FROM SARADAP A
    WHERE A.SARADAP_TERM_CODE_ENTRY LIKE :TERM
    AND A.SARADAP_CAMP_CODE = STVCAMP_CODE
    AND A.SARADAP_DEGC_CODE_1 = STVDEGC_CODE
    AND TO_DATE(TO_CHAR(A.SARADAP_APPL_DATE,'DD/MM/YYYY'),'DD/MM/YYYY') <= TO_DATE(TO_CHAR (SYSDATE,'DD/MM/')||:YEAR,'DD/MM/YYYY')
    ) "REC",
    
    (SELECT COUNT(DISTINCT SARADAP_PIDM) FROM SARADAP A,SARAPPD
    WHERE SARADAP_TERM_CODE_ENTRY LIKE :TERM
    AND SARAPPD_TERM_CODE_ENTRY = SARADAP_TERM_CODE_ENTRY
    AND SARAPPD_PIDM = SARADAP_PIDM
    AND SARAPPD_APPL_NO = SARADAP_APPL_NO
    AND SARAPPD_APDC_CODE = 'AD'
    AND SARAPPD_SEQ_NO = (SELECT 
                            MAX(SARAPPD_SEQ_NO) 
                            FROM SARAPPD 
                            WHERE SARAPPD_PIDM = SARADAP_PIDM 
                            AND SARAPPD_TERM_CODE_ENTRY = SARADAP_TERM_CODE_ENTRY 
                            AND SARAPPD_APPL_NO = SARADAP_APPL_NO 
                            AND SARAPPD_APDC_CODE = 'AD'
                        )
    AND SARADAP_CAMP_CODE = STVCAMP_CODE
    AND A.SARADAP_DEGC_CODE_1 = STVDEGC_CODE
    AND TO_DATE(TO_CHAR(SARAPPD_ACTIVITY_DATE,'DD/MM/YYYY'),'DD/MM/YYYY') <= TO_DATE(TO_CHAR (SYSDATE,'DD/MM/')||:YEAR,'DD/MM/YYYY')) "TOTAL ADMITTED",
    
    (SELECT COUNT(DISTINCT SARADAP_PIDM) FROM SARADAP A,SARAPPD
    WHERE SARADAP_TERM_CODE_ENTRY LIKE :TERM
    AND SARAPPD_TERM_CODE_ENTRY = SARADAP_TERM_CODE_ENTRY
    AND SARAPPD_PIDM = SARADAP_PIDM
    AND SARAPPD_APPL_NO = SARADAP_APPL_NO
    AND SARAPPD_APDC_CODE = 'AD'
    AND SARAPPD_SEQ_NO = (SELECT 
                            MAX(SARAPPD_SEQ_NO) 
                            FROM SARAPPD 
                            WHERE SARAPPD_PIDM = SARADAP_PIDM 
                            AND SARAPPD_TERM_CODE_ENTRY = SARADAP_TERM_CODE_ENTRY 
                            AND SARAPPD_APPL_NO = SARADAP_APPL_NO 
                            AND SARAPPD_APDC_CODE = 'AD'
                        )
    AND SARADAP_CAMP_CODE = STVCAMP_CODE 
    AND A.SARADAP_DEGC_CODE_1 = STVDEGC_CODE
    AND SARADAP_ADMT_CODE = '01'
    
    AND TO_DATE(TO_CHAR(SARAPPD_ACTIVITY_DATE,'DD/MM/YYYY'),'DD/MM/YYYY') <= TO_DATE(TO_CHAR (SYSDATE,'DD/MM/')||:YEAR,'DD/MM/YYYY')) "NEWLY ADMITTED",
    
    (SELECT COUNT(DISTINCT SARADAP_PIDM) FROM SARADAP A,SARAPPD
    WHERE SARADAP_TERM_CODE_ENTRY LIKE :TERM
    AND SARAPPD_TERM_CODE_ENTRY = SARADAP_TERM_CODE_ENTRY
    AND SARAPPD_PIDM = SARADAP_PIDM
    AND SARAPPD_APPL_NO = SARADAP_APPL_NO
    AND SARAPPD_APDC_CODE = 'AD'
    AND SARAPPD_SEQ_NO = (SELECT 
                            MAX(SARAPPD_SEQ_NO) 
                            FROM SARAPPD 
                            WHERE SARAPPD_PIDM = SARADAP_PIDM 
                            AND SARAPPD_TERM_CODE_ENTRY = SARADAP_TERM_CODE_ENTRY 
                            AND SARAPPD_APPL_NO = SARADAP_APPL_NO 
                            AND SARAPPD_APDC_CODE = 'AD'
                        )
    AND SARADAP_CAMP_CODE = STVCAMP_CODE
    AND A.SARADAP_DEGC_CODE_1 = STVDEGC_CODE
    AND SARADAP_ADMT_CODE = '03'
    
    AND TO_DATE(TO_CHAR(SARAPPD_APDC_DATE,'DD/MM/YYYY'),'DD/MM/YYYY') <= TO_DATE(TO_CHAR (SYSDATE,'DD/MM/')||:YEAR,'DD/MM/YYYY')) "ADMITTED RESUMING",
    
    (SELECT COUNT(DISTINCT SARADAP_PIDM) FROM SARADAP A
    WHERE A.SARADAP_TERM_CODE_ENTRY LIKE :TERM
    AND A.SARADAP_CAMP_CODE = STVCAMP_CODE
    AND TO_DATE(TO_CHAR(A.SARADAP_APPL_DATE,'DD/MM/YYYY'),'DD/MM/YYYY') <= TO_DATE(TO_CHAR (SYSDATE,'DD/MM/')||:YEAR,'DD/MM/YYYY')
    AND SARADAP_APST_CODE = 'H'
    AND A.SARADAP_DEGC_CODE_1 = STVDEGC_CODE
    AND NOT EXISTS (SELECT SARADAP_PIDM FROM SARADAP B,SARAPPD D
                        WHERE SARADAP_TERM_CODE_ENTRY LIKE :TERM
                        AND SARAPPD_TERM_CODE_ENTRY = SARADAP_TERM_CODE_ENTRY
                        AND SARAPPD_PIDM = SARADAP_PIDM
                        AND SARAPPD_APPL_NO = SARADAP_APPL_NO
                        AND SARAPPD_APDC_CODE = 'AD'
                        AND SARAPPD_SEQ_NO = (SELECT 
                                                MAX(SARAPPD_SEQ_NO) 
                                                FROM SARAPPD 
                                                WHERE SARAPPD_PIDM = SARADAP_PIDM 
                                                AND SARAPPD_TERM_CODE_ENTRY = SARADAP_TERM_CODE_ENTRY 
                                                AND SARAPPD_APPL_NO = SARADAP_APPL_NO 
                                                AND SARAPPD_APDC_CODE = 'AD'
                                            )
                        AND B.SARADAP_PIDM = A.SARADAP_PIDM
                        AND TO_DATE(TO_CHAR(SARAPPD_ACTIVITY_DATE,'DD/MM/YYYY'),'DD/MM/YYYY') <= TO_DATE(TO_CHAR (SYSDATE,'DD/MM/')||:YEAR,'DD/MM/YYYY'))
    ) "HOLD",
    
    (SELECT COUNT(DISTINCT SARADAP_PIDM) FROM SARADAP A
    WHERE A.SARADAP_TERM_CODE_ENTRY LIKE :TERM
    AND A.SARADAP_CAMP_CODE = STVCAMP_CODE
    AND TO_DATE(TO_CHAR(A.SARADAP_APPL_DATE,'DD/MM/YYYY'),'DD/MM/YYYY') <= TO_DATE(TO_CHAR (SYSDATE,'DD/MM/')||:YEAR,'DD/MM/YYYY')
    AND SARADAP_APST_CODE = 'I'
    AND A.SARADAP_DEGC_CODE_1 = STVDEGC_CODE
    AND NOT EXISTS (SELECT SARADAP_PIDM FROM SARADAP B,SARAPPD D
                        WHERE SARADAP_TERM_CODE_ENTRY LIKE :TERM
                        AND SARAPPD_TERM_CODE_ENTRY = SARADAP_TERM_CODE_ENTRY
                        AND SARAPPD_PIDM = SARADAP_PIDM
                        AND SARAPPD_APPL_NO = SARADAP_APPL_NO
                        AND SARAPPD_APDC_CODE = 'AD'
                        AND SARAPPD_SEQ_NO = (SELECT 
                                                MAX(SARAPPD_SEQ_NO) 
                                                FROM SARAPPD 
                                                WHERE SARAPPD_PIDM = SARADAP_PIDM 
                                                AND SARAPPD_TERM_CODE_ENTRY = SARADAP_TERM_CODE_ENTRY 
                                                AND SARAPPD_APPL_NO = SARADAP_APPL_NO 
                                                AND SARAPPD_APDC_CODE = 'AD'
                                            )
                        AND B.SARADAP_PIDM = A.SARADAP_PIDM
                        AND TO_DATE(TO_CHAR(SARAPPD_ACTIVITY_DATE,'DD/MM/YYYY'),'DD/MM/YYYY') <= TO_DATE(TO_CHAR (SYSDATE,'DD/MM/')||:YEAR,'DD/MM/YYYY'))
    ) "INCOMPLETE",
    
    (SELECT COUNT(DISTINCT SARADAP_PIDM) FROM SARADAP A
    WHERE A.SARADAP_TERM_CODE_ENTRY LIKE :TERM
    AND A.SARADAP_CAMP_CODE = STVCAMP_CODE
    AND TO_DATE(TO_CHAR(A.SARADAP_APPL_DATE,'DD/MM/YYYY'),'DD/MM/YYYY') <= TO_DATE(TO_CHAR (SYSDATE,'DD/MM/')||:YEAR,'DD/MM/YYYY')
    AND SARADAP_APST_CODE = 'P'
    AND A.SARADAP_DEGC_CODE_1 = STVDEGC_CODE
    AND NOT EXISTS (SELECT SARADAP_PIDM FROM SARADAP B,SARAPPD D
                        WHERE SARADAP_TERM_CODE_ENTRY LIKE :TERM
                        AND SARAPPD_TERM_CODE_ENTRY = SARADAP_TERM_CODE_ENTRY
                        AND SARAPPD_PIDM = SARADAP_PIDM
                        AND SARAPPD_APPL_NO = SARADAP_APPL_NO
                        AND SARAPPD_APDC_CODE = 'AD'
                        AND SARAPPD_SEQ_NO = (SELECT 
                                                MAX(SARAPPD_SEQ_NO) 
                                                FROM SARAPPD 
                                                WHERE SARAPPD_PIDM = SARADAP_PIDM 
                                                AND SARAPPD_TERM_CODE_ENTRY = SARADAP_TERM_CODE_ENTRY 
                                                AND SARAPPD_APPL_NO = SARADAP_APPL_NO 
                                                AND SARAPPD_APDC_CODE = 'AD'
                                            )
                        AND B.SARADAP_PIDM = A.SARADAP_PIDM
                        AND TO_DATE(TO_CHAR(SARAPPD_ACTIVITY_DATE,'DD/MM/YYYY'),'DD/MM/YYYY') <= TO_DATE(TO_CHAR (SYSDATE,'DD/MM/')||:YEAR,'DD/MM/YYYY'))
    ) "PENDING USP RESULTS",
    
    (SELECT COUNT(DISTINCT SARADAP_PIDM) FROM SARADAP A
    WHERE A.SARADAP_TERM_CODE_ENTRY LIKE :TERM
    AND A.SARADAP_CAMP_CODE = STVCAMP_CODE
    AND TO_DATE(TO_CHAR(A.SARADAP_APPL_DATE,'DD/MM/YYYY'),'DD/MM/YYYY') <= TO_DATE(TO_CHAR (SYSDATE,'DD/MM/')||:YEAR,'DD/MM/YYYY')
    AND SARADAP_APST_CODE = 'W'
    AND A.SARADAP_DEGC_CODE_1 = STVDEGC_CODE
    AND NOT EXISTS (SELECT SARADAP_PIDM FROM SARADAP B,SARAPPD D
                        WHERE SARADAP_TERM_CODE_ENTRY LIKE :TERM
                        AND SARAPPD_TERM_CODE_ENTRY = SARADAP_TERM_CODE_ENTRY
                        AND SARAPPD_PIDM = SARADAP_PIDM
                        AND SARAPPD_APPL_NO = SARADAP_APPL_NO
                        AND SARAPPD_APDC_CODE = 'AD'
                        AND SARAPPD_SEQ_NO = (SELECT 
                                                MAX(SARAPPD_SEQ_NO) 
                                                FROM SARAPPD 
                                                WHERE SARAPPD_PIDM = SARADAP_PIDM 
                                                AND SARAPPD_TERM_CODE_ENTRY = SARADAP_TERM_CODE_ENTRY 
                                                AND SARAPPD_APPL_NO = SARADAP_APPL_NO 
                                                AND SARAPPD_APDC_CODE = 'AD'
                                            )
                        AND B.SARADAP_PIDM = A.SARADAP_PIDM
                        AND TO_DATE(TO_CHAR(SARAPPD_ACTIVITY_DATE,'DD/MM/YYYY'),'DD/MM/YYYY') <= TO_DATE(TO_CHAR (SYSDATE,'DD/MM/')||:YEAR,'DD/MM/YYYY'))
    ) "COUNSELLING REQUIRED",
    
    (SELECT COUNT(DISTINCT SARADAP_PIDM) FROM SARADAP A
    WHERE A.SARADAP_TERM_CODE_ENTRY LIKE :TERM
    AND A.SARADAP_CAMP_CODE = STVCAMP_CODE
    AND TO_DATE(TO_CHAR(A.SARADAP_APPL_DATE,'DD/MM/YYYY'),'DD/MM/YYYY') <= TO_DATE(TO_CHAR (SYSDATE,'DD/MM/')||:YEAR,'DD/MM/YYYY')
    AND SARADAP_APST_CODE = 'C'
    AND A.SARADAP_DEGC_CODE_1 = STVDEGC_CODE
    AND NOT EXISTS (SELECT SARADAP_PIDM FROM SARADAP B,SARAPPD D
                        WHERE SARADAP_TERM_CODE_ENTRY LIKE :TERM
                        AND SARAPPD_TERM_CODE_ENTRY = SARADAP_TERM_CODE_ENTRY
                        AND SARAPPD_PIDM = SARADAP_PIDM
                        AND SARAPPD_APPL_NO = SARADAP_APPL_NO
                        AND SARAPPD_APDC_CODE = 'AD'
                        AND SARAPPD_SEQ_NO = (SELECT 
                                                MAX(SARAPPD_SEQ_NO) 
                                                FROM SARAPPD 
                                                WHERE SARAPPD_PIDM = SARADAP_PIDM 
                                                AND SARAPPD_TERM_CODE_ENTRY = SARADAP_TERM_CODE_ENTRY 
                                                AND SARAPPD_APPL_NO = SARADAP_APPL_NO 
                                                AND SARAPPD_APDC_CODE = 'AD'
                                            )
                        AND B.SARADAP_PIDM = A.SARADAP_PIDM
                        AND TO_DATE(TO_CHAR(SARAPPD_ACTIVITY_DATE,'DD/MM/YYYY'),'DD/MM/YYYY') <= TO_DATE(TO_CHAR (SYSDATE,'DD/MM/')||:YEAR,'DD/MM/YYYY'))
    ) "AWAITING ASSESSMENT",
    
    (SELECT COUNT(DISTINCT SARADAP_PIDM) FROM SARADAP A
    WHERE A.SARADAP_TERM_CODE_ENTRY LIKE :TERM
    AND A.SARADAP_CAMP_CODE = STVCAMP_CODE
    AND TO_DATE(TO_CHAR(A.SARADAP_APPL_DATE,'DD/MM/YYYY'),'DD/MM/YYYY') <= TO_DATE(TO_CHAR (SYSDATE,'DD/MM/')||:YEAR,'DD/MM/YYYY')
    AND SARADAP_APST_CODE = 'D'
    AND A.SARADAP_DEGC_CODE_1 = STVDEGC_CODE
    AND NOT EXISTS (SELECT SARADAP_PIDM FROM SARADAP B,SARAPPD D
                        WHERE SARADAP_TERM_CODE_ENTRY LIKE :TERM
                        AND SARAPPD_TERM_CODE_ENTRY = SARADAP_TERM_CODE_ENTRY
                        AND SARAPPD_PIDM = SARADAP_PIDM
                        AND SARAPPD_APPL_NO = SARADAP_APPL_NO
                        AND SARAPPD_APDC_CODE = 'AD'
                        AND SARAPPD_SEQ_NO = (SELECT 
                                                MAX(SARAPPD_SEQ_NO) 
                                                FROM SARAPPD 
                                                WHERE SARAPPD_PIDM = SARADAP_PIDM 
                                                AND SARAPPD_TERM_CODE_ENTRY = SARADAP_TERM_CODE_ENTRY 
                                                AND SARAPPD_APPL_NO = SARADAP_APPL_NO 
                                                AND SARAPPD_APDC_CODE = 'AD'
                                            )
                        AND B.SARADAP_PIDM = A.SARADAP_PIDM
                        AND TO_DATE(TO_CHAR(SARAPPD_ACTIVITY_DATE,'DD/MM/YYYY'),'DD/MM/YYYY') <= TO_DATE(TO_CHAR (SYSDATE,'DD/MM/')||:YEAR,'DD/MM/YYYY'))
    ) "DECISION MADE-NOT AD",
    
    (SELECT COUNT(DISTINCT SARADAP_PIDM) FROM SARADAP A,SARAPPD
    WHERE SARADAP_TERM_CODE_ENTRY LIKE :TERM
    AND SARAPPD_TERM_CODE_ENTRY = SARADAP_TERM_CODE_ENTRY
    AND SARAPPD_PIDM = SARADAP_PIDM
    AND SARAPPD_APPL_NO = SARADAP_APPL_NO
    AND SARAPPD_APDC_CODE = 'U3'
    AND A.SARADAP_DEGC_CODE_1 = STVDEGC_CODE
    AND SARAPPD_SEQ_NO = (SELECT 
                            MAX(SARAPPD_SEQ_NO) 
                            FROM SARAPPD 
                            WHERE SARAPPD_PIDM = SARADAP_PIDM 
                            AND SARAPPD_TERM_CODE_ENTRY = SARADAP_TERM_CODE_ENTRY 
                            AND SARAPPD_APPL_NO = SARADAP_APPL_NO 
                            AND SARAPPD_APDC_CODE = 'U3'
                        )
    AND SARADAP_CAMP_CODE = STVCAMP_CODE
    AND TO_DATE(TO_CHAR(SARAPPD_ACTIVITY_DATE,'DD/MM/YYYY'),'DD/MM/YYYY') <= TO_DATE(TO_CHAR (SYSDATE,'DD/MM/')||:YEAR,'DD/MM/YYYY')) "REJECTED",
    
    (SELECT COUNT(DISTINCT SARADAP_PIDM) FROM SARADAP A,SARAPPD
    WHERE SARADAP_TERM_CODE_ENTRY LIKE :TERM
    AND SARAPPD_TERM_CODE_ENTRY = SARADAP_TERM_CODE_ENTRY
    AND SARAPPD_PIDM = SARADAP_PIDM
    AND SARAPPD_APPL_NO = SARADAP_APPL_NO
    AND SARAPPD_APDC_CODE = 'L2'
    AND A.SARADAP_DEGC_CODE_1 = STVDEGC_CODE
    AND SARAPPD_SEQ_NO = (SELECT 
                            MAX(SARAPPD_SEQ_NO) 
                            FROM SARAPPD 
                            WHERE SARAPPD_PIDM = SARADAP_PIDM 
                            AND SARAPPD_TERM_CODE_ENTRY = SARADAP_TERM_CODE_ENTRY 
                            AND SARAPPD_APPL_NO = SARADAP_APPL_NO 
                            AND SARAPPD_APDC_CODE = 'L2'
                        )
    AND SARADAP_CAMP_CODE = STVCAMP_CODE
    AND TO_DATE(TO_CHAR(SARAPPD_ACTIVITY_DATE,'DD/MM/YYYY'),'DD/MM/YYYY') <= TO_DATE(TO_CHAR (SYSDATE,'DD/MM/')||:YEAR,'DD/MM/YYYY')) "OL GENERATED"
    
    FROM STVCAMP,STVDEGC,
    (SELECT DISTINCT SARADAP_DEGC_CODE_1 FROM SARADAP A WHERE A.SARADAP_TERM_CODE_ENTRY = 201403 ) PROG
    WHERE STVCAMP_CODE NOT IN ('X','F','P','W')
    
    AND STVDEGC_CODE = PROG.SARADAP_DEGC_CODE_1
    
    ORDER BY 1,2
    

1 个答案:

答案 0 :(得分:2)

立即引起我注意的是这些日期转换:

TO_DATE(TO_CHAR(SARAPPD_ACTIVITY_DATE,'DD/MM/YYYY'),'DD/MM/YYYY')

如果这些日期列上有索引,则由于这些转换,数据库将无法使用它们。他们为什么需要呢?摆脱它们。