2011-06-07 90 views
0

我需要從一個表和一個視圖連接到2列中獲取結果。在oracle中的查詢優化

查看:800萬記錄 表:5K記錄

我通過查詢計劃順利進行,並觀察該查詢將需要很長時間來運行和INFACT嘗試運行此查詢,但沒有得到任何結果。

請幫我優化查詢。我沒有使用任何提示。

SELECT coupon_upc 
    , sum (loyalty_a) a 
    , sum (loyalty_b) b 
    , sum (loyalty_c) c 
    , sum (loyalty_x) 
    FROM (SELECT ccd.coupon_upc          AS coupon_upc 
       , (CASE WHEN a.loyalty_cell = 'A' then 1 else 0 end) AS loyalty_a 
       , (CASE WHEN a.loyalty_cell = 'B' then 1 else 0 end) AS loyalty_b 
       , (CASE WHEN a.loyalty_cell = 'C1' then 1 else 0 end) AS loyalty_c 
       , (CASE WHEN a.loyalty_cell = 'X' then 1 else 0 end) AS loyalty_x 
      FROM view1 a 
       , (select distinct coupon_upc 
           , coupon_id 
           , division 
          from table2 
          where schedule_key = 'XXX') ccd 
      WHERE a.campaign_code = 'XXX' 
      AND a.coupon_id = ccd.coupon_id 
      AND a.division = ccd.division) a 
GROUP BY coupon_upc 
+2

提供查詢和表/視圖DDL語句可以更容易地幫助你。 – Datajam 2011-06-07 09:14:59

+1

如果有可能使用MVIEW而不是VIEW並在其上創建索引? – mcha 2011-06-07 09:23:33

+0

沒有權利這樣做! – SouravM 2011-06-07 09:27:04

回答

1

沒有解釋計劃或模式/ DDL,可以完成的優化量是有限的。

下面是一個替代方案,但您需要測試它,看看它是否有任何區別。 (替換爲相關子查詢中使用聯接)

SELECT 
    coupon_upc, sum(loyalty_a) a, sum(loyalty_b) b, sum(loyalty_c) c, sum(loyalty_x) x 
FROM 
    (
    SELECT 
    (
    SELECT 
     coupon_upc 
    FROM 
     table2 
    WHERE 
     schedule_key = 'XXX' 
     AND coupon_id = a.coupon_id 
     AND division = a.division 
    GROUP BY 
     coupon_upc 
    ) as coupon_upc, 
    (case when a.loyalty_cell = 'A' then 1 else 0 end) as loyalty_a, 
    (case when a.loyalty_cell = 'B' then 1 else 0 end) as loyalty_b, 
    (case when a.loyalty_cell = 'C1' then 1 else 0 end) as loyalty_c, 
    (case when a.loyalty_cell = 'X' then 1 else 0 end) as loyalty_x 
    FROM 
    view1 a 
    WHERE 
    a.campaign_code = 'XXX'  
) a 
GROUP BY 
    coupon_upc 

除此之外,那種的優化是:
- 堅持認爲
- 指標
- 重構數據結構

編輯

查詢的另一個可能的重構......我不知道甲骨文將如何優化4個相關子查詢的實例。

SELECT 
    coupon_upc, 
    SUM((SELECT COUNT(*) FROM view1 WHERE campaign_code = 'XXX' AND loyalty_cell = 'A' AND coupon_id = map.coupon_id AND division = map.division)) AS loyalty_a, 
    SUM((SELECT COUNT(*) FROM view1 WHERE campaign_code = 'XXX' AND loyalty_cell = 'B' AND coupon_id = map.coupon_id AND division = map.division)) AS loyalty_b, 
    SUM((SELECT COUNT(*) FROM view1 WHERE campaign_code = 'XXX' AND loyalty_cell = 'C1' AND coupon_id = map.coupon_id AND division = map.division)) AS loyalty_c, 
    SUM((SELECT COUNT(*) FROM view1 WHERE campaign_code = 'XXX' AND loyalty_cell = 'X' AND coupon_id = map.coupon_id AND division = map.division)) AS loyalty_x 
FROM 
    (
    SELECT coupon_upc, coupon_id, division 
    FROM table2 WHERE schedule_key = 'xxx' 
    GROUP BY coupon_upc, coupon_id, division 
) 
    AS map 
GROUP BY 
    coupon_upc 

或者,也許......

SELECT 
    map.coupon_upc, SUM(data.loyalty_a) AS a, SUM(data.loyalty_b) AS b, SUM(data.loyalty_c) AS c, SUM(data.loyalty_x) AS X 
FROM 
    (
    SELECT coupon_upc, coupon_id, division 
    FROM table2 WHERE schedule_key = 'xxx' 
    GROUP BY coupon_upc, coupon_id, division 
) 
    AS map 
INNER JOIN 
    (
    SELECT 
    coupon_id, 
    division, 
    SUM(CASE WHEN loyalty_cell = 'A' THEN 1 ELSE 0 END) AS loyalty_a, 
    SUM(CASE WHEN loyalty_cell = 'B' THEN 1 ELSE 0 END) AS loyalty_b, 
    SUM(CASE WHEN loyalty_cell = 'C1' THEN 1 ELSE 0 END) AS loyalty_c, 
    SUM(CASE WHEN loyalty_cell = 'X' THEN 1 ELSE 0 END) AS loyalty_x 
    FROM 
    view1 
    WHERE 
    campaign_code = 'XXX' 
) 
    AS data 
    ON data.coupon_id = map.coupon_id 
    AND data.division = map.division 
GROUP BY 
    map.coupon_upc 
1

另一個可能改寫爲:

SELECT 
    map.coupon_upc 
    , COUNT(CASE WHEN a.loyalty_cell = 'A' THEN 1 ELSE NULL END) AS loyalty_a 
    , COUNT(CASE WHEN a.loyalty_cell = 'B' THEN 1 ELSE NULL END) AS loyalty_b 
    , COUNT(CASE WHEN a.loyalty_cell = 'C1' THEN 1 ELSE NULL END) AS loyalty_c 
    , COUNT(CASE WHEN a.loyalty_cell = 'X' THEN 1 ELSE NULL END) AS loyalty_x 
FROM 
    (SELECT coupon_upc, coupon_id, division 
    FROM table2 WHERE schedule_key = 'xxx' 
    GROUP BY coupon_upc, coupon_id, division 
) AS map 
    JOIN view1 a 
    ON a.coupon_id = map.coupon_id 
    AND a.division = map.division 
WHERE 
    a.campaign_code = 'xxx' 
GROUP BY 
    map.coupon_upc 

你對那些在JOINWHEREGROUP BY使用的字段索引條款?