在oracle中创建表需要额外的时间

时间:2014-04-30 13:41:16

标签: sql oracle

我使用下面的代码来创建表,这应该最多需要30分钟。但有一段时间需要超过90分钟。请帮我修改一下

    create table age_temp
    as
    SELECT co.circle, co.canumber, sum(age1) age1, sum(age2) age2, sum(age3) age3,         sum(age4) age4,
            sum(age5) age5, sum(age6) age6, sum(age7) age7, sum(age8) age8
    FROM
    (SELECT cta.szpartitionfield circle, cta.ifield1 CANUMBER,
            CASE WHEN ohstatus IN ('CO','CM') THEN
                    ohopnamt_doc
                 ELSE CASE  WHEN ohstatus IN ('IN','FC') THEN
                                    CASE WHEN MONTHS_BETWEEN(SYSDATE,ohrefdate) < 1  THEN
                                            ohopnamt_doc
                                    ELSE 0
                                    END
                            ELSE 0
                            END
                 END age1,
            CASE WHEN ohstatus IN ('IN','FC') THEN
                      CASE WHEN MONTHS_BETWEEN(SYSDATE,ohrefdate) >= 1  AND
                                MONTHS_BETWEEN(SYSDATE,ohrefdate) < 2  THEN
                                    ohopnamt_doc
                           ELSE 0
                           END
                 END age2,
            CASE WHEN ohstatus IN ('IN','FC') THEN
                      CASE WHEN MONTHS_BETWEEN(SYSDATE,ohrefdate) >= 2  AND
                                MONTHS_BETWEEN(SYSDATE,ohrefdate) < 3  THEN
                                    ohopnamt_doc
                           ELSE 0
                           END
                 END age3,
            CASE WHEN ohstatus IN ('IN','FC') THEN
                      CASE WHEN MONTHS_BETWEEN(SYSDATE,ohrefdate) >= 3  AND
                                MONTHS_BETWEEN(SYSDATE,ohrefdate) < 4  THEN
                                    ohopnamt_doc
                           ELSE 0
                           END
             END age4,
        CASE WHEN ohstatus IN ('IN','FC') THEN
                  CASE WHEN MONTHS_BETWEEN(SYSDATE,ohrefdate) >= 4  AND
                            MONTHS_BETWEEN(SYSDATE,ohrefdate) < 5  THEN
                                ohopnamt_doc
                       ELSE 0
                       END
             END age5,
        CASE WHEN ohstatus IN ('IN','FC') THEN
                  CASE WHEN MONTHS_BETWEEN(SYSDATE,ohrefdate) >= 5  AND
                            MONTHS_BETWEEN(SYSDATE,ohrefdate) < 6  THEN
                                ohopnamt_doc
                       ELSE 0
                       END
             END age6,
        CASE WHEN ohstatus IN ('IN','FC') THEN
                  CASE WHEN MONTHS_BETWEEN(SYSDATE,ohrefdate) >= 6  AND
                            MONTHS_BETWEEN(SYSDATE,ohrefdate) < 7  THEN
                                ohopnamt_doc
                       ELSE 0
                       END
             END age7,
        CASE WHEN ohstatus IN ('IN','FC') THEN
                  CASE WHEN MONTHS_BETWEEN(SYSDATE,ohrefdate) >= 7  THEN
                                ohopnamt_doc
                       ELSE 0
                       END
                  ELSE 0
                  END age8 
     FROM 
         CDCDATA.ORDERHDR_ALL ORD, cash_temp ct, CDCDATA.customer_all cu, CMS_CDC.COL_TRN_AGREEMENT cta where ct.customer_id = ORD.customer_id 
     and ord.customer_id = cu.customer_id
     and cu.custnum = cta.szlegacyagreementno ) co 
     GROUP BY  co.circle, co.canumber;

2 个答案:

答案 0 :(得分:0)

如果没有获取此查询中使用的基表(或其他表)的实际数据和表结构的详细信息,则很难修改查询。但下面可能会有所帮助:

  1. 在花费超过预期时间时,检查是否在创建此表的同时运行任何其他进程。可能是某些其他进程阻止了一个表,如果这些表或占用了所有资源。

  2. 检查并行性 - 不使用并行,看看需要多长时间并使用该参数。需要考虑并行级别的基表。

  3. 将此查询拆分为多个查询 - 您当前正在按案例,分组等处理数据。将每个操作拆分为单独的查询。

  4. 希望这会有所帮助。

答案 1 :(得分:0)

尝试使用一个支点(下面可能不完全正常,因为我没有样本数据,但应该让你走上正确的轨道):

WITH prep AS (
  SELECT
      cta.szpartitionfield circle
    , cta.ifield1 canumber
    , CASE
        WHEN ohstatus IN('CO', 'CM') THEN 1
        ELSE MAX(MIN(CEIL(MONTHS_BETWEEN(SYSDATE, ohrefdate)),8),1)
      END piv_col
      -- Round the 'months_between' up and cap it at 8
      -- Then force CO and CM stats to be 1 since we want them added in there
      -- Make sure no negatives or 0s get in... probably not needed
    , CASE WHEN ohstatus IN('IN', 'FC') THEN ohopnamt_doc ELSE 0 END ohstat
      -- Will only be non-zero for IN or FC status
    FROM cdcdata.orderhdr_all ord
      INNER JOIN cash_temp ct
        ON ord.customer_id = ct.customer_id
      INNER JOIN cdcdata.customer_all cu
        ON ord.customer_id = cu.customer_id
      INNER JOIN cms_cdc.col_trn_agreement cta
        ON cu.custnum = cta.szlegacyagreementno
)
SELECT *
  FROM prep PIVOT(
    SUM(ohstat) -- Sum, split by values 1-8
    FOR (piv_col) IN (
      1 AS age1, 2 AS age2, 3 AS age3, 4 AS age4
    , 5 AS age5, 6 AS age6, 7 AS age7, 8 AS age8
    )
  )
;

这应该产生一个如下所示的结果集:

CIRCLE   CANUMBER  AGE1  AGE2  AGE3  AGE4  AGE5  AGE6  AGE7  AGE8
------- --------- ----- ----- ----- ----- ----- ----- ----- -----
a               1     5     1     5    12     1     0    12    16
b               2     2     5    12     7     4     2     3     3
c               3     0     3     2     1     0    21     5     3
d               4     1     2     1     1     7     5     3    11

希望这有帮助!

如果没有,请为每个表发布DESCRIBE输出,并从每个表中发布一些相互关联的样本数据(5行)。

此外,您为表格设置了别名,但ohstatus ohrefdate ohopnamt_doc列没有别名,因此我必须在整个连接而不是特定表格上进行准备工作(我有点假设它们来自cdcdata.orderhdr_all),这可能会节省一些处理时间。