2010-06-28 68 views
1

我正在瀏覽一些沒有評論的pl/sql代碼。嘗試理解並優化它。下面是示例:我該如何優化這些oracle查詢集

INSERT INTO gtt1 --75711 rows 
(USER_ID, role_id, participant_code, status_id) 
SELECT 
r.user_id, r.role_id, r.participant_code, MAX(status_id) 
FROM 
    user_role r, 
    cmp_role c 
WHERE 
    r.role_id = c.role_id 
    AND r.participant_code IS NOT NULL 
    AND c.group_id = 3 
    GROUP BY 
    r.user_id, r.role_id, r.participant_code; 

然後

DELETE gtt1 
WHERE ROWID IN (SELECT ROWID FROM gtt1 
       MINUS 
       SELECT a.ROWID FROM gtt1 a, UIV_CMP_USER_ROLE b 
       WHERE a.status_id = b.status_id 
       AND (b.ACTIVE = 1 OR (b.ACTIVE IN (0,3) 
         AND SYSDATE BETWEEN b.effective_from_date AND b.effective_to_date 
        ) 
       ) 
       ); 

最後(這需要最長)

OPEN cv_1 FOR 

SELECT c.role_id, 
     c.subgroup, 
     c.subgroup_description, 
     COUNT(a.USER_ID) user_count 
FROM 
    (SELECT b.user_id, b.role_id FROM gtt1 b, pt_user e 
    --pt_user table has 73000 rows 
     WHERE e.user_id = RTRIM(b.user_id) 
     ) a 
RIGHT OUTER JOIN CMP_ROLE c ON a.role_id = c.role_id 
WHERE c.group_id = v_group_id 
GROUP BY c.role_id,c.subgroup,c.subgroup_description 
ORDER BY c.subgroup; 

有沒有一種方法可以讓我避免gtt1刪除,最初只得到行我們想?

運行解釋計劃我注意到這個查詢的一些全表掃描:

SELECT 
    r.user_id, r.role_id, r.participant_code, MAX(status_id) 
    FROM 
    user_role r, 
    cmp_role c 
    WHERE 
    r.role_id = c.role_id 
    AND r.participant_code IS NOT NULL 
    AND c.group_id = 3 
    GROUP BY 
    r.user_id, r.role_id, r.participant_code 
    HAVING MAX(status_id) IN (SELECT b.status_id FROM UIV_CMP_USER_ROLE b 
           WHERE (b.ACTIVE = 1 OR (b.ACTIVE IN (0,3) 
            AND SYSDATE BETWEEN b.effective_from_date AND b.effective_to_date 
            )) 
          ) 

USER_ROLE = 803507行

cmp_role = 27行

user_role的有5個指標:

idx 1 = role_id

IDX 2 = last_updt_user_id

IDX 3 = actv_id,participant_code,effective_from_Date,effective_to_date

IDX 4 = USER_ID,ROLE_ID,effective_from_Date,effective_to_date

IDX 5 = participant_code,USER_ID,roke_id,actv_cd

+0

gtt1在您的查詢中是否始終保持一致?他們是順序查詢嗎?也許你可以試着把它們寫成一個而不是三個查詢? – 2010-06-28 12:18:38

回答

0

插入和刪除在我看來是相同的:

INSERT INTO gtt1 --75711 rows 
(USER_ID, role_id, participant_code, status_id) 
SELECT 
r.user_id, r.role_id, r.participant_code, MAX(status_id) 
FROM 
    user_role r, 
    cmp_role c 
WHERE 
    r.role_id = c.role_id 
    AND r.participant_code IS NOT NULL 
    AND c.group_id = 3 
    GROUP BY 
    r.user_id, r.role_id, r.participant_code 
    HAVING MAX(status_id) IN (SELECT b.status_id FROM UIV_CMP_USER_ROLE b 
          WHERE (b.ACTIVE = 1 OR (b.ACTIVE IN (0,3) 
            AND SYSDATE BETWEEN b.effective_from_date 
               AND b.effective_to_date 
           )) 
          ); 

這是否是更有效的,我不知道 - 我需要更多地瞭解表格,索引和數據。

你可以去再進一步,並打開GTT爲子查詢,例如:

WITH gtt1 AS 
    (SELECT 
    r.user_id, r.role_id, r.participant_code, MAX(status_id) 
    FROM 
    user_role r, 
    cmp_role c 
    WHERE 
    r.role_id = c.role_id 
    AND r.participant_code IS NOT NULL 
    AND c.group_id = 3 
    GROUP BY 
    r.user_id, r.role_id, r.participant_code 
    HAVING MAX(status_id) IN (SELECT b.status_id FROM UIV_CMP_USER_ROLE b 
           WHERE (b.ACTIVE = 1 OR (b.ACTIVE IN (0,3) 
            AND SYSDATE BETWEEN b.effective_from_date AND b.effective_to_date 
            )) 
          ) 
) 
SELECT c.role_id, 
     c.subgroup, 
     c.subgroup_description, 
     COUNT(a.USER_ID) user_count 
FROM 
    (SELECT b.user_id, b.role_id FROM gtt1 b, pt_user e 
    --pt_user table has 73000 rows 
     WHERE e.user_id = RTRIM(b.user_id) 
     ) a 
RIGHT OUTER JOIN CMP_ROLE c ON a.role_id = c.role_id 
WHERE c.group_id = v_group_id 
GROUP BY c.role_id,c.subgroup,c.subgroup_description 
ORDER BY c.subgroup; 

同樣,我不知道這是否是比當前代碼或多或少效率。

+0

託尼,聯合的'WITH AS'查詢完美無缺,但我仍然需要一些時間。我提供了所有表中的行。你能否看看它是否可以在某處進行優化? – Mehur 2010-06-28 20:52:01

+0

我並不感到驚訝,查詢涉及一些完整的掃描:cmp_role只有27行,所以全面掃描是有意義的,並且對user_role的全面掃描也可以有意義,如果它的許多行將匹配參與者代碼不符合的條件null和group_id = 3(有多少user_role行滿足這些條件BTW?) – 2010-06-29 08:46:49

+0

39392行在運行該查詢時返回,它需要19秒。 – Mehur 2010-06-29 11:12:47

1

你想優化查詢本身還是隻需要花費時間來給出結果? 其次大約需要行數的一些數據等等...

+0

只是結果所需的時間。我將爲每個使用的表格提供更多的行數 – Mehur 2010-06-28 18:58:14