Oracle11g中,为了改善DBMS_STATS包收集统计信息时的唯一值计数功能,增加了 APPROX_COUNT_DISTINCT函数,但文档中未记载。Oracle12c文档中包括了该函数,因此,我们现在可以在应用中随意使用它。

1.    基本用法

先前的数据库版本中,如果我们想进行唯一值计数,我们可能会这么做。

SELECT COUNT(DISTINCT c_name) AS nm_cnt

FROM   test;

NM_CNT

----------

58172

1 row selected.

SQL>

该查询会基于Oracle的读一致模型得出精确的唯一值结果。即,我们会看到已提交的数据,及当前会话做的未提交修改。

相反,新函数APPROX_COUNT_DISTINCT不会给出精确结果,但会和精确结果有所偏差。

SELECT APPROX_COUNT_DISTINCT(c_name) AS nm_cnt

FROM   test;

NM_CNT

----------

56789

1 row selected.

SQL>

该函数能用于分组查询中。

SELECT tablespace_name,APPROX_COUNT_DISTINCT(table_name) AS tab_count

FROM   user_tables

GROUP BY tablespace_name

ORDER BY tablespace_name;

TABLESPACE_NAME                 TAB_COUNT

------------------------------ ----------

SYSAUX                                 78

SYSTEM                                 22

USERS                                   7

48

4 rows selected.

SQL>

2.    性能

下例中,我们会看到两种方法性能的差别,但似乎不是特别大。

SET TIMING ON

SELECT COUNT(DISTINCT c_name) AS nm_cnt

FROM   test;

NM_CNT

----------

58172

1 row selected.

Elapsed: 00:00:02.39

SQL>

SELECT APPROX_COUNT_DISTINCT(c_name) AS nm_cnt

FROM   test;

NM_CNT

----------

56789

1 row selected.

Elapsed: 00:00:02.00

SQL>

事实上,APPROX_COUNT_DISTINCT函数被用来处理大得多的负载,下面,我们创建一个大得多的表。

DROP TABLE test PURGE;

CREATE TABLE test AS

SELECT level AS  data

FROM  dual

CONNECT BY level <= 10000;

INSERT /*+ APPEND */ INTO test

SELECT a.data FROM test a

CROSS JOIN test b;

COMMIT;

EXEC DBMS_STATS.gather_table_stats(‘Test’,'Test');

现在表中有100多万数据,1万个唯一值。我们会看到两种方法的性能差别比较大。

SET TIMING ON

SELECT COUNT(DISTINCT data) AS data_count

FROM  test;

DATA_COUNT

----------

10000

1 row selected.

Elapsed: 00:00:19.66

SQL>

SELECT APPROX_COUNT_DISTINCT(data) ASdata_count

FROM  test;

DATA_COUNT

----------

10030

1 row selected.

Elapsed: 00:00:10.46

SQL>

通过测试会发现,之前的方法,当数据量越来越大时,消耗的时间和资源也会越来越大,而新函数APPROX_COUNT_DISTINCT在数据量越来越大时,消耗的时间和资源基本不变。

最新文章

  1. mysql主从复制replication的一些相关命令
  2. codeforces A. Rook, Bishop and King 解题报告
  3. .net学习笔记---IIS 处理模型及ASP.NET页面生命周期
  4. DF学Mysql(三)——Mysql数据类型
  5. DTCMS清除&amp;emsp;&amp;amp;
  6. android系统架构图
  7. Supervisor的一些基础使用
  8. PHP命名空间(Namespace)的使用详解(转)
  9. 201521123109 《java程序设计》第11周学习总结
  10. 经典排序算法 — C# 版(上)
  11. Vue的学习
  12. Attention Is All You Need 一些好的资料
  13. 检索 COM 类工厂中 CLSID 为 {10021F00-E260-11CF-AE68-00AA004A34D5} 的组件失败,原因是出现以下错误: 80040154 没有注册类 (异常来自 HRESULT:0x80040154 (REGDB_E_CLASSNOTREG))。
  14. Win7/Win10下搭建Go语言开发环境
  15. 禁用IE缓存
  16. 沉淀,再出发:python中的pandas包
  17. Django ajax方法提交表单,及后端接受数据
  18. Ecplise添加XML自动提示
  19. 0.00-050613_boot.s
  20. Android(java)学习笔记81:在TextView组件中利用Html插入文字或图片

热门文章

  1. Linux系统对IO端口和IO内存的管理
  2. 微信小程序——3、逻辑js文件
  3. STM32各个文件介绍、uCOSII文件介绍
  4. VC++使用服务做守护进程的示例(转载)
  5. bzoj 3343: 教主的魔法
  6. sql server 存储过程 procedure
  7. lncRNA研究利器之&quot;TANRIC&quot;
  8. Linux(CentOS 6.5) 下安装MySql 5.7.18 二进制版本粗浅攻略
  9. python 判断一个数字是否为3的幂
  10. sudo: /etc/sudoers is world writable sudo: no valid sudoers sources found, q...