位置: 编程技术 - 正文

MySQL中distinct语句去查询重复记录及相关的性能讨论

编辑:rootadmin

推荐整理分享MySQL中distinct语句去查询重复记录及相关的性能讨论,希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:,内容如对您有帮助,希望把文章链接给更多的朋友!

在 MySQL 查询中,可能会包含重复值。这并不成问题,不过,有时您也许希望仅仅列出不同(distinct)的值。

关键词 DISTINCT 用于返回唯一不同的值,就是去重啦。用法也很简单:

DISTINCT 这个关键字来过滤掉多余的重复记录只保留一条。

另外,如果要对某个字段去重,可以试下:

这个用法,MySQL的版本不能太低。

在编写查询之前,我们甚至应该对过滤条件进行排序,真正高效的条件(可能有多个,涉到同的表)是查询的主要驱动力,低效条件只起辅助作用。那么定义高效过滤条件的准则是什呢?首先,要看过滤条件能否尽快减少必须处理的数据量。所以,我们必须倍加关注条件的写方式。假设有四个表: customers 、 orders 、 orderdetail 、 articles ,现在假设 SQL 要处理的问题是:找出最近六个月内居住在 Gotham 市、订购了蝙蝠车的所有客户。当然,编写这个查询有多种方法, ANSI SQL 的推崇者可能写出下列语句:

MySQL中distinct语句去查询重复记录及相关的性能讨论

其中, somefunc 是个函数,返回距今六个月前的具体日期。注意上面用了 distinct ,因为考虑到某个客户可以是大买家,最近订购了好几台蝙蝠车。暂不考虑优化器将如何改写此查询,我们先看一下这段代码的含义。首先,来自 customers 表的数据应只保留城市名为 Gotham 的记录。接着,搜索 orders 表,这意味着 custid 字段最好有索引,否则只有通过排序、合并或扫描 orders 表建立一个哈希表才能保证查询速度。对 orders 表 ,还要针对订单日期进行过滤:如果优化器比较聪明,它会在连接( join )前先过滤掉一些数据,从而减少后面要处理的数据量;不太聪明的优化器则可能会先做连接,再作过滤,这时在连接中指定过滤条件利于提高性能,例如:

注意,如果是:

此处关于left表的筛选条件将失效,因为是左外连接,左表的所有列都将出现在这次连接结果集中)。即使过滤条件与连接( join )无关,优化器也会受到过滤条件的影响。例如,若 orderdetail 的主键为( ordid, artid ),即 ordid 为索引的第一个属性,那么我们可以利用索引找到与订单相关的记录。但如果主键是( artid, ordid )就太不幸了(注意,就关系理论而言 ,无论哪个版本都是完全一样),此时的访问效率比( ordid, artid )作为索引时要差,甚至一些数据库产品无法使用该索引(注 3 ),唯一的希望就是在ordid 上加独立索引了。连接了表 orderdetail 和 orders 之后,来看 articles 表,这不会有问题,因为表 order 包括 artid 字段。最后,检查 articles 中的值是否为 Batmobile 。查询就这样结束了,因为用了 distinct ,通过层层筛选的客户名还必须要排序,以剔除重复项目。避免在最高层使用 distinct 应该是一条基本规则 。原因在于,即使我们遗漏了连接的某个条件, distinct 也会使查询 " 看似正确 " 地执行 —— 无可否认,发现重复数据容易,发现数据不准确很难,所以避免在最高层使用 distinct 应该是一条基本规则。发现结果不正确更难,例如,如果恰巧有多位客户都叫 " Wayne " , distinct 不但会剔除由同个客户的多张订单产生的重复项目,也会剔除由名字相同的不同客户产生的重复项目。事实上,应该同时返回具唯一性的客户 ID 和客户名,以保证得到蝙蝠车买家的完整清单。要摆脱 distinct ,可考虑以下思路:客户在 Gohtam 市,而且满足存在性测试,即在最近六个月订购过蝙蝠车。注意,多数(但非全部) SQL 方言支持以下语法:

上例的存在性测试,同一个名字可能出现多次,但每个客户只出现一次,不管他有多少订单。有人认为我对 ANSI SQL 语法的挑剔有点苛刻(指 " 蝙蝠车买主 " 的例子),因为上面代码中customers 表的地位并没有降低。其实,关键区别在于,新查询中 customers 表是查询结果的唯一来源(嵌套的子查询会负责找出客户子集),而先前的查询却用了 join 。这个嵌套的子查询与外层的 select 关系十分密切。如代码第 行所示(粗体部分),子查询参照了外层查询的当前记录,因此,内层子查询就是所谓的关联子查询( correlated subquery )。此类子查询有个弱点,它无法在确定当前客户之前执行。如果优化器不改写此查询,就必须先找出每个客户,然后逐一检查是否满足存在性测试,当来自 Gotham 市的客户非常少时执行效率倒是很高,否则情况会很糟(此时,优秀的优化器应尝试其他执行查询的方式)。

在这个例子中,内层查询不再依赖外层查询,它已变成了非关联子查询( uncorrelated subquery ),只须执行一次。很显然,这段代码采用了原有的执行流程。在本节的前一个例子 中 ,必须先搜寻符合地点条件的客户(如均来自 GOTHAM ),接着依次检查各个订单。而现在,订购了蝙蝠车的客户,可以通过内层查询获得。不过,如果更仔细地分析一下,前后两个版本的代码还有些更微妙的差异。含关联子查询的代码中,至关重要的是 orders 表中的 custid 字段要有索引,而这对另一段代码并不重要,因为这时要用到的索引(如果有的话)是表 customers 的主键索引。你或许注意到,新版的查询中执行了隐式的 distinct 。的确,由于连接操作,子查询可能会返回有关一个客户的多条记录。但重复项目不会有影响,因为 in 条件只检查该项目是否出现在子查询返回的列表中,且 in 不在乎某值在列表中出现了一次还是一百次。但为了一致性,作为整体,应该对子查询和主查询应用相同的规则,也就是在子查询中也加入存在性测试:

或者

尽管嵌套变得更深、也更难懂了,但子查询内应选择 exists 还是 in 的选择规则相同:此选择取决于日期与商品条件的有效性。除非过去六个月的生意非常清淡,否则商品名称应为最有效的过滤条件,因此子查询中用 in 比 exists 好,这是因为,先找出所有蝙蝠车的订单、再检查销售是否发生在最近六个月,比反过来操作要快。如果表 orderdetail 的 artid 字段有索引,这个方法会更快,否则,这个聪明巧妙的举措就会黯然失色。每当对大量记录做存在性检查时,选择 in 还是 exists 须斟酌。利于多数 SQL 方言,非关联子查询可以被改写成 from 子句中的内嵌视图。然而,一定要记住的是, in 会隐式地剔除重复项目,当子查询改写为 from 子句中的内嵌视图时,必须要显式地消除重复项目。例如:

总结:保证 SQL 语句返回正确结果,只是建立最佳 SQL 语句的第一步。

MySQL中索引优化distinct语句及distinct的多字段操作 MySQL通常使用GROUPBY(本质上是排序动作)完成DISTINCT操作,如果DISTINCT操作和ORDERBY操作组合使用,通常会用到临时表.这样会影响性能.在一些情况下,MySQL可以使

MySQL中distinct语句的基本原理及其与group by的比较 DISTINCT实际上和GROUPBY操作的实现非常相似,只不过是在GROUPBY之后的每组中只取出一条记录而已。所以,DISTINCT的实现和GROUPBY的实现也基本差不多,没有

MySQL中distinct与group by语句的一些比较及用法讲解 在数据表中记录了用户验证时使用的书目,现在想取出所有书目,用DISTINCT和groupby都取到了我想要的结果,但我发现返回结果排列不同,distinct会按数据

标签: MySQL中distinct语句去查询重复记录及相关的性能讨论

本文链接地址:https://www.jiuchutong.com/biancheng/319723.html 转载请保留说明!

上一篇:mysql报错:MySQL server version for the right syntax to use near type=InnoDB的解决方法(mysql1290报错)

下一篇:MySQL中索引优化distinct语句及distinct的多字段操作(mysql索引优化的方案)

  • 我国增值税的纳税人是如何管理的
  • 我公司租了个人的房子如何入账
  • 关税计入存货成本分录
  • 以前年度损益科目核算业务
  • 小规模核定征收需要做账吗
  • 房地产开发企业预收款预缴增值税
  • 如何让自己公司成为供应商
  • 已入账未抵扣退回发票
  • 公司注销应付款太多
  • 增值税扣完税款还能更改吗
  • 事业单位专项资金的管理要求
  • 收到补助款的会计分录
  • 往来核算在会计哪个科目
  • 企业给员工购买社保的规定
  • 增值税设备抵扣怎么抵扣
  • 增值税发票地址开错了有影响吗
  • 怎么判断分红前已提取足够法定公积金?
  • 给客户退差价怎么说
  • 建筑安装预缴增值税
  • 我的初级备考日记--你都没坚持,还谈什么未来
  • 企业已确认销售收入的售出商品发生销售折让,且不属于
  • 餐查账征收企业所得税会计分录?
  • 清理备用金
  • 汇算清缴的租赁费怎么算
  • w11如何激活
  • windows10如何开机启动软件
  • 哪些固定资产不会随着时间的流逝贬值
  • 原材料进项税税率
  • 购买预付卡如何记账
  • 股权出资成立公司的条件
  • linux入门学习
  • php

  • 长期挂账的在建工程如何处理
  • 深入解析wordpress
  • 没签订采购合同怎么办
  • yii框架文档
  • centos 安装php
  • 低代码开发开源
  • php常用array函数
  • 自动化工具 业务有哪些
  • Vue3【Transition(效果、CSS 过渡、使用animation、TransitionGroup、 KeepAlive、Teleport )】(七)-全面详解(学习总结---从入门到深化)
  • js生成随机数字和字母组合
  • 不征税收入的账务处理
  • 航天金税盘维护费什么时候交
  • 其他综合收益属于什么类
  • 营业税改增值税的背景
  • 事业单位应当按月对固定资产计提折旧
  • 织梦图集的使用教程
  • 简易征收预缴税款
  • 车辆购置税如何在电子税务局缴纳
  • sql server 2016 sp3
  • sql server的数据库
  • 继续教育的相关知识
  • 解决问题
  • 长期待摊费用好处
  • 认缴制的注册资金怎么算
  • 基金可以一次性全部卖出吗
  • 母公司和子公司是两个完全独立的法人
  • 无形资产内部研究开发支出的处理
  • 财务费用和应付利息都在借方
  • 软件行业成本如何归集
  • 销项税现金流量附表如何指定
  • 不同利益主体之间的利益如何协调
  • 费用多计提了怎么办
  • mysql在本地主机创建用户账号
  • Windows server 2008下如何安装应用程序
  • osx10.11.6版本如何
  • linux命令行怎么查看公网ip
  • 进程mmc.exe
  • centos中netspeeder网络加速/优化器的安装方法
  • json和ui
  • jquery 表单
  • numpy使用心得
  • android mat
  • javascript面向对象编程指南第三版
  • 熟练使用jquery
  • 全国残疾人工作先进个人
  • 回迁房子契税怎么算
  • 住房公积金补扣
  • 税务打虚打骗
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设