【问题标题】:Between taking longer time. Tuning SQL query之间需要更长的时间。调优 SQL 查询
【发布时间】:2016-11-11 08:16:34
【问题描述】:

我有以下查询,对于一组第 1345222 行,执行时间大约需要 20 分钟。我有办法对此进行调整,特别是 Between 子句比较?

<code>
SELECT /*+ PARALLEL(32) */ upexp.item,
                  upexp.loc,
                  startdate,
                  sku_exp.bucket_size,
                  MAX(upexp.sku_multiplier) OVER (PARTITION BY upexp.item,upexp.loc) max_sm
                        FROM
                                (SELECT bucket bkt,
                                        MIN(dates) OVER (PARTITION BY bucket) minbk,
                                        MAX(dates)  OVER (PARTITION BY bucket) maxbk
                                FROM (
                                        SELECT LEVEL AS sl,
                                        NEXT_DAY (TRUNC (SYSDATE, 'YEAR') + 7 * LEVEL - 8,'SATURDAY') AS dates,
                                        CEIL (LEVEL/4) AS bucket
                                        FROM DUAL
                                        CONNECT BY LEVEL <= ((4 - MOD (78, 4) + 78) + 78)) yy
                               -- GROUP BY bucket
                                ) minmaxdate ,
                        stsc.u_promo_sku_expand sku_exp,
                        stsc.u_promo_upload_expand upexp
                        WHERE sku_exp.bucket_size = 4
                        AND sku_exp.startdate BETWEEN minmaxdate.minbk AND minmaxdate.maxbk
                        AND upexp.item = sku_exp.item
                        AND upexp.loc = sku_exp.loc
                        AND upexp.u_country = sku_exp.u_country
                        AND ((eff BETWEEN minmaxdate.minbk AND minmaxdate.maxbk+6)
                        OR ( disc BETWEEN minmaxdate.minbk AND minmaxdate.maxbk+6)
                        OR ( eff <= minmaxdate.minbk AND disc >= minmaxdate.maxbk+6))

</code>

【问题讨论】:

  • 计划在哪里? '(eff BETWEEN minmaxdate.minbk AND minmaxdate.maxbk+6) 或 eff = minmaxdate.maxbk+6)' 在最后一个谓词部分在任何情况下都是正确的
  • 您是否为实际表定义了任何索引?另外,我不太明白为什么您在整个查询中都有SELECT ... FROM DUAL。不能搬出去吗?
  • 尝试使用 group by both ,而不是 MIN/MAX OVER。并将通过查询连接到 WITH
  • 计划中完全使用了高DOP?
  • @FDavidov: 是的,我在实际表上有索引。无法删除 SELECT FROM DUAL ,因为我需要计算从年初到 n 天的最小和最大日期(仅星期六),桶 = 4。也就是说,前 4 个星期六是 1 组,然后是接下来的四个星期六是另一组等等...

标签: sql oracle query-performance


【解决方案1】:

这个区块

(SELECT bucket bkt,
   MIN(dates) OVER (PARTITION BY bucket) minbk,
   MAX(dates)  OVER (PARTITION BY bucket) maxbk
FROM (
     SELECT LEVEL AS sl,
         NEXT_DAY (TRUNC (SYSDATE, 'YEAR') + 7 * LEVEL - 8,'SATURDAY') AS dates,
         CEIL (LEVEL/4) AS bucket
     FROM DUAL
     CONNECT BY LEVEL <= ((4 - MOD (78, 4) + 78) + 78)) yy
     -- GROUP BY bucket
     )

似乎没用,因为您只需要最小值和最大值。

试试这个:

WITH minmaxdate AS
   (SELECT 
       NEXT_DAY (TRUNC (SYSDATE, 'YEAR') + 7 * 1 - 8,'SATURDAY') AS minbk,
       NEXT_DAY (TRUNC (SYSDATE, 'YEAR') + 7 * ((4 - MOD (78, 4) + 78) + 78) - 8,'SATURDAY') AS maxbk
    FROM dual)
SELECT item, loc, startdate, sku_exp.bucket_size,
    MAX(upexp.sku_multiplier) OVER (PARTITION BY item, loc) max_sm
FROM stsc.u_promo_sku_expand sku_exp
    JOIN stsc.u_promo_upload_expand upexp USING (item, loc, u_country)
    CROSS JOIN minmaxdate
WHERE sku_exp.bucket_size = 4
    AND sku_exp.startdate BETWEEN minmaxdate.minbk AND minmaxdate.maxbk
    AND (
        eff BETWEEN minmaxdate.minbk AND minmaxdate.maxbk+6 
        OR (eff <= minmaxdate.minbk AND disc >= minmaxdate.maxbk+6)
        OR disc BETWEEN minmaxdate.minbk AND minmaxdate.maxbk+6
    );

【讨论】:

  • 我得到这个:ORA-25154:USING 子句的列部分不能有限定符。但这很好用。 SELECT item, loc, startdate, bucket_size --MAX(sku_multiplier) OVER (PARTITION BY sku_exp.item,sku_exp.loc) max_sm FROM stsc.u_promo_sku_expand sku_exp JOIN stsc.u_promo_upload_expand upexp USING (item, loc, u_country) WHERE sku_exp.bucket_size = 4
猜你喜欢
  • 2016-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
相关资源
最近更新 更多