签到成功

知道了

CNDBA社区CNDBA社区

oracle 19c 去重统计函数 APPROX_COUNT_DISTINCT 说明

2022-02-11 12:05 2153 0 原创 Oracle 19c
作者: dave

在Oracle 数据库中去重统计是一个常规的操作, 在Oracle 12c 之前的版本中,一般使用COUNT (DISTINCT expr) 来实现。 但当表数据量巨大时,该语法性能较差。 因此,在Oracle 12c中,引入了APPROX_COUNT_DISTINCT 函数。

http://www.cndba.cn/dave/article/106645

官网对其描述如下:

http://www.cndba.cn/dave/article/106645
http://www.cndba.cn/dave/article/106645

https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/APPROX_COUNT_DISTINCT.html

APPROX_COUNT_DISTINCT returns the approximate number of rows that contain a distinct value for expr.

This function provides an alternative to the COUNT (DISTINCT expr) function, which returns the exact number of rows that contain distinct values of expr. APPROX_COUNT_DISTINCT processes large amounts of data significantly faster than COUNT, with negligible deviation from the exact result.

For expr, you can specify a column of any scalar data type other than BFILE, BLOB, CLOB, LONG, LONG RAW, or NCLOB.

APPROX_COUNT_DISTINCT ignores rows that contain a null value for expr. This function returns a NUMBER.

根据说明,就是在12c 以后的版本,建议使用APPROX_COUNT_DISTINCT 代替COUNT (DISTINCT expr) 函数。实际上,在Oracle 19c中,对COUNT DISTINCT做了进一步的优化,为特定SQL带来极大性能提升。http://www.cndba.cn/dave/article/106645

但是在12c 的版本中,该函数有几个bug。 如果执行遇到问题,建议升级到19c版本。

http://www.cndba.cn/dave/article/106645
http://www.cndba.cn/dave/article/106645

Bug 18121220 - ORA-600 [kghfrempty:ds] on Query using APPROX_COUNT_DISTINCT (Doc ID 18121220.8)
Bug 22631327 - ORA-600 [15851] on group by rollup using approx_count_distinct (Doc ID 22631327.8)
Bug 29331066 - vector_transform does not support approx_count_distinct (Doc ID 29331066.8)

官网给到我们的2个SQL 示例, 如下:

http://www.cndba.cn/dave/article/106645
http://www.cndba.cn/dave/article/106645

SELECT APPROX_COUNT_DISTINCT(manager_id) AS "Active Managers"
  FROM employees;

Active Managers
---------------
             18

SELECT prod_id, APPROX_COUNT_DISTINCT(cust_id) AS "Number of Customers"
  FROM sales
  GROUP BY prod_id
  ORDER BY prod_id;

   PROD_ID Number of Customers
---------- -------------------
        13                2516
        14                2030
        15                2105
        16                2367
        17                2093
        18                2975
        19                2630
        20                3791
. . .

对比下2个函数的执行时间,APPROX_COUNT_DISTINCT 确实也是要快很多:

http://www.cndba.cn/dave/article/106645
http://www.cndba.cn/dave/article/106645

正常查看不同object_name的总数
15:39:31 SQL> select count(distinct(object_name)) from cndba_t;

COUNT(DISTINCT(OBJECT_NAME))
---------------------------
       67455

Elapsed: 00:00:00.64

使用APPROX_COUNT_DISTINCT()
15:39:36 SQL> select APPROX_COUNT_DISTINCT(object_name) from cndba_t;

APPROX_COUNT_DISTINCT(OBJECT_NAME)
----------------------------------
     67063

Elapsed: 00:00:00.14

版权声明:本文为博主原创文章,未经博主允许不得转载。

用户评论
* 以下用户言论只代表其个人观点,不代表CNDBA社区的观点或立场
dave

dave

关注

人的一生应该是这样度过的:当他回首往事的时候,他不会因为虚度年华而悔恨,也不会因为碌碌无为而羞耻;这样,在临死的时候,他就能够说:“我的整个生命和全部精力,都已经献给世界上最壮丽的事业....."

  • 2261
    原创
  • 3
    翻译
  • 578
    转载
  • 191
    评论
  • 访问:7971174次
  • 积分:4346
  • 等级:核心会员
  • 排名:第1名
精华文章
    最新问题
    查看更多+
    热门文章
      热门用户
      推荐用户
        Copyright © 2016 All Rights Reserved. Powered by CNDBA · 皖ICP备2022006297号-1·

        QQ交流群

        注册联系QQ