广告
返回顶部
首页 > 资讯 > 数据库 >DISTICT的一次质疑
  • 412
分享到

DISTICT的一次质疑

2024-04-02 19:04:59 412人浏览 八月长安
摘要

一直以来DISTINCT的用法都为DBA所知,就是用来滤重。我们也没有必要质疑DISTINCT的滤重准确性。但今天突然不知道怎么想的,就想质疑一下。DISTINCT真的能保证过滤的对象没有重复记录吗?sql

一直以来DISTINCT的用法都为DBA所知,就是用来滤重。我们也没有必要质疑DISTINCT的滤重准确性。

但今天突然不知道怎么想的,就想质疑一下。DISTINCT真的能保证过滤的对象没有重复记录吗?

sql> create table test_distinct as select rownum id from all_objects where rownum < 50000;
insert into test_distinct select rownum id from all_objects where rownum < 50000;

这表中有重复的数据,数据插入顺序1~4999,然后再重复一次

SQL> select count(id) from (select distinct id from test_distinct) group by id having count(id) > 1;
no rows selected

可以看到,通过这条语句发现确实没有重复的行。那么进一步思考如果不用distinct如何实现这个效果呢。我想起了ROWID这个东西,以下两句的效果相同。

select count(distinct phoneno) from CUSTPHONE

select count(phoneno) from CUSTPHONE where rowid in( select min(rowid) from CUSTPHONE group by phoneno)

我想了解一下DISTINCT语句实际在oracle中是如何操作的,通过10046事件和tkprof工具获取跟踪的信息。

SQL ID: 8vtyapcbqkbwf
Plan Hash: 2372476266
select distinct id
from
 test_distinct where rownum < 100

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.02       0.02          0        138          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        8      0.00       0.00          0          4          0          99
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total       10      0.02       0.02          0        142          0          99
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: SYS
Rows     Row Source Operation
-------  ---------------------------------------------------
     99  HASH UNIQUE (cr=4 pr=0 pw=0 time=0 us cost=528 size=1287 card=99)
     99   COUNT STOPKEY (cr=4 pr=0 pw=0 time=196 us)
     99    TABLE ACCESS FULL TEST_DISTINCT (cr=4 pr=0 pw=0 time=98 us cost=44 size=1318174 card=101398)

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  SQL*Net message to client                       8        0.00          0.00
  asynch descriptor resize                        2        0.00          0.00
  SQL*Net message from client                     8       59.43         59.43

可以看到执行计划中DISINCT是通过HASH UNIQUE算法来实现的。同时ROWNUM虚列使用的是COUNT算法,STOPKEY说明我给ROWNUM虚列加了限定条件100,当到达这个限定条件时,该语句查询结束。

那么到这我该怎么理解HASH UNIQUE算法的目的呢?我在网上查看了相关信息,发现真有人做了实验实验帮助我们加上对该算法的印象。在10G2R以前,Oracle对DISTINCT使用的是sort unique这种操作方式因为涉及到排序,是非常影响语句的执行效率的。因此10G2R之后的版本,Oracle改进了算法。

SQL> select distinct id from test_distinct where rownum < 100;
99 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 2372476266
---------------------------------------------------------------------------------------------
| Id  | Operation           | Name          | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |               |    99 |  1287 |       |   528   (1)| 00:00:07 |
|   1 |  HASH UNIQUE        |               |    99 |  1287 |  2000K|   528   (1)| 00:00:07 |
|*  2 |   COUNT STOPKEY     |               |       |       |       |            |          |
|   3 |    TABLE ACCESS FULL| TEST_DISTINCT |   101K|  1287K|       |    44   (3)| 00:00:01 |
---------------------------------------------------------------------------------------------
Predicate InfORMation (identified by operation id):
---------------------------------------------------
   2 - filter(ROWNUM<100)
Note
-----
   - dynamic sampling used for this statement (level=2)

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          4  consistent gets
          8  physical reads
          0  redo size
       2134  bytes sent via SQL*Net to client
        589  bytes received via SQL*Net from client
          8  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         99  rows processed

SQL> alter system flush buffer_cache

SQL> select id from test_distinct where rownum < 100 group by id;
99 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 521476922
-------------------------------------------------------------------------------------
| Id  | Operation           | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |               |    99 |  1287 |    47   (9)| 00:00:01 |
|   1 |  HASH GROUP BY      |               |    99 |  1287 |    47   (9)| 00:00:01 |
|*  2 |   COUNT STOPKEY     |               |       |       |            |          |
|   3 |    TABLE ACCESS FULL| TEST_DISTINCT |   101K|  1287K|    44   (3)| 00:00:01 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter(ROWNUM<100)
Note
-----
   - dynamic sampling used for this statement (level=2)

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          4  consistent gets
          8  physical reads
          0  redo size
       2134  bytes sent via SQL*Net to client
        589  bytes received via SQL*Net from client
          8  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         99  rows processed

通过网上这组实验可以看到DISTINCT和GROUP BY分别使用了HASH UNIQUE和HASH GROUP BY算法。而两者执行效果和结果都相同。基于规则的DISTINCT和GROUP BY的查询的执行计划如下

SQL> select  distinct id from test_distinct where rownum < 100;
99 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 3449293992
---------------------------------------------
| Id  | Operation           | Name          |
---------------------------------------------
|   0 | SELECT STATEMENT    |               |
|   1 |  SORT UNIQUE        |               |
|*  2 |   COUNT STOPKEY     |               |
|   3 |    TABLE ACCESS FULL| TEST_DISTINCT |
---------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter(ROWNUM<100)
Note
-----
   - rule based optimizer used (consider using cbo)

Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          4  consistent gets
          8  physical reads
          0  redo size
       2134  bytes sent via SQL*Net to client
        589  bytes received via SQL*Net from client
          8  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
         99  rows processed

 
SQL> select  id from test_distinct where rownum < 100 group by id;
99 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 351786816
---------------------------------------------
| Id  | Operation           | Name          |
---------------------------------------------
|   0 | SELECT STATEMENT    |               |
|   1 |  SORT GROUP BY      |               |
|*  2 |   COUNT STOPKEY     |               |
|   3 |    TABLE ACCESS FULL| TEST_DISTINCT |
---------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter(ROWNUM<100)
Note
-----
   - rule based optimizer used (consider using cbo)

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          4  consistent gets
          8  physical reads
          0  redo size
       2134  bytes sent via SQL*Net to client
        589  bytes received via SQL*Net from client
          8  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
         99  rows processed

因为表的数据量教啥,基于rule的算法和通过hash的算法区别并不明显。但重点在于了解Oracle的不同算法的可能。

另外,ORACLE除了提供DISTINCT以外,还提供了UNIQUE来过滤重复的数据。官方文档给出的解释。

Http://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_10002.htm#SQLRF55272

DISTINCT | UNIQUE

Specify DISTINCT or UNIQUE if you want the database to return only one copy of each set of duplicate rows selected. These two keyWords are synonymous. Duplicate rows are those with matching values for each expression in the select list.

到这里我已经理解了DISTINCT的作用,同时还学习了其它新的知识。非常棒!

您可能感兴趣的文档:

--结束END--

本文标题: DISTICT的一次质疑

本文链接: https://www.lsjlt.com/news/38885.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • DISTICT的一次质疑
    一直以来DISTINCT的用法都为DBA所知,就是用来滤重。我们也没有必要质疑DISTINCT的滤重准确性。但今天突然不知道怎么想的,就想质疑一下。DISTINCT真的能保证过滤的对象没有重复记录吗?SQL...
    99+
    2022-10-18
  • 有关mongodb升级的一些疑问
    我们的mongodb数据库是简单的一主一从架构,目前是2.4版本,我想升级到3.2,网上介绍的方式基本都是一步步升级的那种,我有一种升级想法,那就是,用3.2启一个从库,等同步完成后直接把这个3.2从库关闭...
    99+
    2022-10-18
  • 解读C#中ReadString的一些小疑惑
    目录ReadString的一些小疑惑BinaryReader . ReadString 方法  ()总结ReadString的一些小疑惑 BinaryReader . Re...
    99+
    2023-01-28
    C# ReadString C# ReadString疑惑 ReadString小疑惑
  • 【Otter】关于otter双A模式的一点疑问
    何为双A模式:可以简单理解为mysql的双主模式,互为主从 具体可参考:https://github.com/alibaba/otter/wiki/Manager配置介绍 官方博客的配置方法: 双A...
    99+
    2022-10-18
  • 聊一聊关于php源码中refcount的疑问
    在浏览PHP源码的时候,在众多的*.stub.php中,发现了这样的注释,@refcount 1。 通过翻看build/gen_stub.php源码,发现了在解析*.stub.php...
    99+
    2022-11-13
    php源码refcount php @refcount 1
  • ​MySQL 一个让你怀疑人生的hang死现象
    1、故障现象 某客户反馈,在利用binlog日志的解析内容做基于时间点的恢复时,出现hang死(超过12小时那种),恢复过程无法继续,而且100%重现 基于时间点恢复的实现方式为:使用mysqlb...
    99+
    2022-10-18
  • Scrapy:python3下的第一次运
    1,引言《Scrapy的架构初探》一文讲解了Scrapy的架构,本文就实际来安装运行一下Scrapy爬虫。本文以官网的tutorial作为例子,完整的代码可以在github上下载。2,运行环境配置本次测试的环境是:Windows10, Py...
    99+
    2023-01-31
    Scrapy
  • 一次意外的ORA-12520
    问题描述:前几天临时接到通知说一套运行很多年的应用程序连接不上数据库,但上午都是正常的,通过netmanager,pl/sql以及在数据库服务器上以sqlplux xx/xx@service_name测试连...
    99+
    2022-10-18
  • 记一次goagent的设置
    设置GoAgent代理服务器的步骤如下:1. 下载并安装GoAgent客户端。可以在GoAgent官方网站或者GitHub上找到最新...
    99+
    2023-09-21
    goagent
  • 安装Mysql时可能会遇到的一些疑难杂症
    问题一: 在安装时候输入 net start mysql 时候报错为: net不是内部或外部命令也不是可运行。 解决方法: 环境变量的问题: 首先确定C:\Windows\System32下有net.exe。 在一下...
    99+
    2022-05-26
    mysql安装失败 mysql linux安装教程 mysql8安装教程
  • 分享一次数据库SQL查询的数次轮回
    本篇内容主要讲解“分享一次数据库SQL查询的数次轮回”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“分享一次数据库SQL查询的数次轮回”吧!我们使用数据库,直观感...
    99+
    2022-10-18
  • 记一次CurrentDirectory导致的问题
    在编程中,CurrentDirectory是一个表示当前工作目录的属性。它指示了程序在运行时所在的目录。一次由CurrentDire...
    99+
    2023-09-15
    问题
  • 记一次MySQL的优化案例
    一  背景       有赞的每个OLTP数据库实例上会设置一个sql-killer进程用于kill 掉执行时间超过一定阈值的sql。下午开发接收到sql被kill的报错,一起...
    99+
    2022-05-16
    MySQL 优化 MySQL 优化案例
  • 一次故障转移的排错
    ...
    99+
    2022-10-18
  • 记一次springboot中用undertow的坑
    目录springboot中用undertow的坑本文实验的环境如下环境准备使用springboot2.2.11、springboot2.2.12、springboot2.2.13如果...
    99+
    2022-11-13
  • 书写高质量SQL的一些建议
    select * from employee; 正例子: selectid,namefrom employee; 理由: 只取需要的字段,节省资源、减少网络开销。 select * ...
    99+
    2017-02-17
    书写高质量SQL的一些建议
  • HTTP二维码API:Java的一次探索
    随着移动互联网的普及,二维码已经成为了一种非常方便的信息传递方式。在很多场景下,我们需要通过二维码来传递信息,比如说产品推广、活动宣传等等。而在Java开发中,我们可以使用HTTP二维码API来快速生成二维码。 HTTP二维码API是一种...
    99+
    2023-08-23
    http 二维码 api
  • 记一次使用nacos2踩到的坑
    前言 本文素材来源朋友学习nacos2.1.1踩到的坑。直接上正菜 坑点一:出现端口被占用 因为是学习使用,朋友就在物理机搭建了搭建了nacos伪集群,即ip都一样,端口分别为8848,8847,88...
    99+
    2023-09-17
    nginx 服务器 运维 springcloud
  • leetcode之只出现一次的数字
    今天为大家分享的是关于在数组中找到只出现一次数字的系列题目,我将使用c跟Java来实现,希望我的分享能够帮助到大家。 文章目录 初阶查找单身狗理解题目做题思路C语言代码实现Java代码实现 ...
    99+
    2023-09-21
    leetcode c语言 java
  • oracle导出、导入的一次实战
    刚到公司没多久,就有一台oracle服务器要进行导出、导入,以前接触过oracle,可是对oracle导出、导入没研究过,这下急坏我了,于是赶紧上网恶补了一下。操作结果如下:Oracle 数据导出导入第一步...
    99+
    2022-10-18
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作