繁体   English   中英

oracle 中的查询优化

[英]Query Optimization in oracle

我需要从一张表中获取结果,并在 2 列上加入一个视图。

查看:800 万条记录表:5K 条记录

我浏览了查询计划并观察到查询将需要很长时间才能运行,实际上尝试运行此查询但没有得到任何结果。

请帮助我优化查询。我没有使用任何提示。

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

如果没有解释计划或模式/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

除此之外,优化的种类是:
- 坚持观点
- 索引
- 重构数据结构

编辑

查询的另一个可能的重构......我不知道 Oracle 将如何优化相关子查询的 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

另一种可能的重写是:

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子句中使用的字段有索引吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM