oracle 中 DENSE_RANK() 的性能问题视图

Posted

技术标签:

【中文标题】oracle 中 DENSE_RANK() 的性能问题视图【英文标题】:Performance issue view with DENSE_RANK() in oracle 【发布时间】:2019-03-18 12:41:52 【问题描述】:

我们要求从下表中获取具有上述匹配条件的记录并将 UNIQUE COL3 的计数限制为 20K。

我们通过使用DENSE_RANK() 逻辑实现了这一点,但我们发现在实时系统中实现时性能极其缓慢。

要处理 20K UNIQUE COL3 和 60K 总记录,需要 14-15 小时才能完成(该过程在每日 JOB 上运行并选择 FROM 视图并根据查看记录对少数表执行 DML 操作)。

SELECT COUNT (distinct COL3) CNT1,COUNT(1) CNT2 FROM VW_ENTP;
--20,000                                                  60,000

没有 DENSE_RAN() 逻辑它完成得非常快,但使用 DENSE_RAN() 它非常慢。

请求您的帮助以分享任何关于提高查询性能的建议或任何替代方法。提前致谢!

示例查看代码

CREATE OR REPLACE VIEW VW_ENTP(COL1, COL2, COL3, COL4, COL5, COL6, COL7, COL8, COL9, COL10) AS
SELECT
COL1, COL2, COL3, COL4, COL5, COL6, COL7, COL8, COL9, COL10
 FROM
(
SELECT
           NP.NFCD COL1,
           D.CLO2 COL2,
           NP.COL3 COL3,
           E.COL4 COL4,
           EDT.COL5,
           EDT.COL6,
           NP. COL7,
           NP. COL8,
           EDT.COL9 COL9,
           NP.COL10,
           DENSE_RANK() OVER (ORDER BY NP.COL3) RANK
  FROM ENP NP,EDTS EDT,EM E,EDT D,BDT BD
WHERE EDT.COL2=D.COL2
  AND E.COL3=NP.COL3
  AND E.COL7=NP.COL7
  AND E.COL8=NP.COL8
  AND E.APP=NP.APP
  AND NP.STATUS='P'
  AND NP.NFCD=D.COL1
  AND E.SUSP !='YES'
  AND NP.APP='EDOC'
  AND TRUNC(NP.RC_DATE)<=TRUNC(BD.LAST_RUN_DATE)
)
  WHERE RANK<=20000;

注意:以上使用的列已编入索引。

【问题讨论】:

专家您好-有什么更新吗?任何想法将不胜感激。 【参考方案1】:

通常,如果错过任何连接条件,则会导致性能下降。此外,您正在加入其他几个表,并且任何表都可能导致性能问题。只有看过这些表格后才能给出对它们的建议。

要确认密集等级是否导致问题,您可以将其删除并执行 select 语句。如果花费的时间更少,那么您可以得出结论,密集等级是导致问题的原因。但我高度怀疑它会发生。

【讨论】:

是的,我们已经执行了 SQL,但它没有按预期工作。 然后从 select 语句中删除排名。将 select 语句放在 WITH 子句中。然后对 WITH 类的结果应用 rank 函数。它必须有效。 没有排名功能性能很好。使用排名功能,性能很差 - 这是不可能的。我认为您在代码中要么撒谎要么犯错误。没有排名功能和您的 oracle 版本的结果记录数是多少? Oracle 版本-> Oracle 12c 企业版记录处理-> SELECT COUNT (distinct COL3) CNT1,COUNT(1) CNT2 FROM VW_ENTP; --19,000 30,000【参考方案2】:

您只能通过 row_number() 函数来实现:

CREATE OR REPLACE VIEW VW_ENTP(COL1, COL2, COL3, COL4, COL5, COL6, COL7, COL8, COL9, COL10) AS
SELECT
COL1, COL2, COL3, COL4, COL5, COL6, COL7, COL8, COL9, COL10
 FROM
(select a.*, row_number() over (order by col3) rn from (
SELECT
           NP.NFCD COL1,
           D.CLO2 COL2,
           NP.COL3 COL3,
           E.COL4 COL4,
           EDT.COL5,
           EDT.COL6,
           NP. COL7,
           NP. COL8,
           EDT.COL9 COL9,
           NP.COL10,
           row_number() OVER (partition by np.col3 ORDER BY NP.COL3) RANK
  FROM ENP NP,EDTS EDT,EM E,EDT D,BDT BD
WHERE EDT.COL2=D.COL2
  AND E.COL3=NP.COL3
  AND E.COL7=NP.COL7
  AND E.COL8=NP.COL8
  AND E.APP=NP.APP
  AND NP.STATUS='P'
  AND NP.NFCD=D.COL1
  AND E.SUSP !='YES'
  AND NP.APP='EDOC'
  AND TRUNC(NP.RC_DATE)<=TRUNC(BD.LAST_RUN_DATE)
) a where rank > 1 and rank <= 20000) 

;

当前查询结果:

COL3 排名

1 1

2 1

3 1

3 2

3 3

3 4

4 1

5 1

要求:

COL3 排名

1 1

2 2

3 3

3 3

3 3

3 3

4 4

5 5

【讨论】:

您好 Vinish-请注意,COL3 有重复记录,排名逻辑已用于限制每次调用视图时 20k 重复 COL3。 你试过上面的查询吗?您尝试它应该可以工作...无需使用密集等级..您的目的将通过此解决.. 我认为替换不同的分析函数不会解决性能问题。您是否有一个基准可以证明 row_number() 的性能比 dense_rank() 有显着提高? 哦.. 将一个(别名)如下所示:) a where rank = 1) WHERE Rn 执行了查询,但我现在只看到唯一记录计数(请参阅下面的输出)要求获取所有重复的 COL3,但每个 COL3 的计数应为

以上是关于oracle 中 DENSE_RANK() 的性能问题视图的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 中 rownumrow_number()rank()dense_rank() 函数的用法

MySQL中是不是有像Oracle这样的dense_rank()和row_number()这样的函数?

Oracle中rank() over, dense_rank(), row_number() 的区别

将 Oracle 查询中的 keep dense_rank 转换为 postgres

Oracle Order by - 基于函数 (dense_rank)

[转]oracle分析函数Rank, Dense_rank, row_number