作者:蒋步星

来源:数据蒋堂

本文共1600字,建议阅读7分钟。
我们是否可以利用“后半”有序的特点提高性能呢?

上一期我们说了前半有序的数据,这次我们来看看“后半”有序的情况。

回顾一下前半有序的说法:我们要把数据集T按字段a,b排序时,如果T已经对a有序,则可以利用这一特点实现高性能算法。但后半有序却不是对称地把问题理解成T已经对b有序时要对a,b排序的任务,这个“后半”序信息并没有多大利用价值。这里说的“后半”有序问题是指:如果T已经对a,b有序,现在我们要将T按b排序。

这其实是很常见的情况。多维分析的数据集一般总会按某套(比如按日期、帐户)维度已经排好序,但我们可能希望按第二维度(帐户)再排序或分组,是否可以利用这个特点提高性能呢?


我们用a(i),b(i)表示表T中第i条记录的字段a,b取值。T对a,b有序,意味着如果a(i)=a(i+1)则必然有b(i)<=b(i+1),即相邻的a值相同的记录的b值会构成一个有序子集。这时候如果我们能够把这些有序子集都找出来(遍历一次将a值发生变化的位置记下来即可)再进行归并排序,就可以得到对b有序的结果集了。而归并排序的复杂度相对较低(nlogk,k是归并路数,一般远小于n),遍历一次的成本也不算高(相对于排序算法的复杂度nlogn),看起来这会是一个有效的手段。

但是,我们产生了一批有这样特征的数据来做实验,发现并没有比直接针对b使用快速排序(Quicksort)算法有明显的优势。

其实道理很简单,快速排序本来就是一种递归的分段排序再归并的算法,对于一个已经大体有序的数组,快速排序的速度已经能够很快。它的复杂度nlogn是指平均情况,对于上述这种“后半”有序的b值来讲,快速排序的复杂度也就是相当于nlogk的复杂度,和我们设想的办法一样。


这个方法对于排序没有效果,但对于分组却有意义。

我们把任务改变一下:对T按b分组并计算每个组的某种聚合值。

通用分组算法一般采用hash方案,即计算每个分组键的hash值,相同hash值的记录被分拣到一个小集合,然后在这个小集合内遍历找同值再聚合。复杂度,也就是比较次数,取决于hash函数重码率。在hash空间比较小的时候,重码率就会比较高,比较次数会较多,性能就受影响。为了保证性能,就需要分配较大的内存来存放hash表。另外,有些数据类型(长字串)的hash计算也比较慢,这也会影响性能。

而如果利用“后半”有序的特征则可以避免hash运算。我们将数据按b排序,然后再执行有序分组,即每条记录只与上一条记录比较,发现有不同时则新建一个分组,相同则聚合到当前组中。这样的分组运算的复杂度为n,而且没有hash计算和重码率的问题。如果排序足够快,就可以获得比hash分组更快的性能,而且并不需要太多内存用于存放hash表。

没有这个“后半”有序的前提时,先排序的时间成本通常会很高,超过hash分组的耗时。所以,排序分组的方案虽然简单易行,但商用数据库一般却不采用,有些开源数据库或报表工具为了图省事才会使用。然而,如果数据满足了这个条件时,排序就会快很多,有序分组的时间复杂度又很低,这样配合起来就可以获得更高的分组性能。


排序分组还有个好处在于,结果集是天然有序的。这样,易于实现大数据以及分布式分组运算。

目前的大数据分组一般也是采用hash方案,将原始数据先根据hash值分成几堆,然后分别针对每一堆再做分组。如果是分布式系统,在“分堆”时就会有大量的网络传输动作。而如果数据满足“后半”有序的条件,则可以采用类似大排序的方案来做分组,即读入每一段后进行排序分组再写出成临时数据,然后再将这些临时数据归并,因为每一段临时数据都是有序的,后续的归并就可以进行。在分布式运算时也可以每个分机独立做分组,最后统一归并汇总即可,过程中只有归并那一步需要网络传输。


排序分组算法因为性能不佳而在大多数场合被弃用,但在特定条件下却又能发挥出更好的效果。其实很少有什么算法一定好或一定坏,适合数据和运算特征的算法才是好算法。

在内存中要执行排序分组算法很简单,只要分两步先排序再分组就可以了,用基本方法组合即可,不需要实现专门方法。而对于大数据则不可以先做排序后再基于结果再做分组,因为大排序本身就要写出缓存数据,再来一轮大分组又写一次,就得不偿失了。针对大数据执行排序分组算法需要把这个算法固化到分组运算中,而不能用基本运算组合出来。所以,集算器在大分组方法中提供了选项供程序员根据现场情况决定是否使用排序分组算法。

专栏作者简介

润乾软件创始人、首席科学家

清华大学计算机硕士,中国大数据产业生态联盟专家委员,著有《非线性报表模型原理》等,1989年,中国首个国际奥林匹克数学竞赛团体冠军成员,个人金牌;2000年,创立润乾公司;2004年,首次在润乾报表中提出非线性报表模型,完美解决了中国式复杂报表制表难题,目前该模型已经成为报表行业的标准;2014年,经过7年开发,润乾软件发布不依赖关系代数模型的计算引擎——集算器,有效地提高了复杂结构化大数据计算的开发和运算效率;2015年,润乾软件被福布斯中文网站评为“2015福布斯中国非上市潜力企业100强”;2016、2017年,荣获中国电子信息产业发展研究院评选的“中国软件和信息服务业十大领军人物”;2017年度中国数据大工匠、数据领域专业技术讲堂《数据蒋堂》创办者。

数据蒋堂

《数据蒋堂》的作者蒋步星,从事信息系统建设和数据处理长达20多年的时间。他丰富的工程经验与深厚的理论功底相互融合、创新思想与传统观念的相互碰撞,虚拟与现实的相互交织,产生出了一篇篇的沥血之作。此连载的内容涉及从数据呈现、采集到加工计算再到存储以及挖掘等各个方面。大可观数据世界之远景、小可看技术疑难之细节。针对数据领域一些技术难点,站在研发人员的角度从浅入深,进行全方位、360度无死角深度剖析;对于一些业内观点,站在技术人员角度阐述自己的思考和理解。蒋步星还会对大数据的发展,站在业内专家角度给予预测和推断。静下心来认真研读你会发现,《数据蒋堂》的文章,有的会让用户避免重复前人走过的弯路,有的会让攻城狮面对扎心的难题茅塞顿开,有的会为初入行业的读者提供一把开启数据世界的钥匙,有的甚至会让业内专家大跌眼镜,产生思想交锋。

数据蒋堂第二年往期回顾:

数据蒋堂 | 存储和计算技术的选择

数据蒋堂 | 人工智能中的“人工”

数据蒋堂 | 中国报表漫谈

数据蒋堂 | 内存数据集产生的隐性成本

数据蒋堂 | 多维分析预汇总的功能盲区

数据蒋堂 | 多维分析预汇总的存储容量

数据蒋堂 | 多维分析预汇总的方案探讨

数据蒋堂 | 数据库的封闭性

数据蒋堂 | 内存数据集产生的隐性成本

数据蒋堂 | 前半有序的大数据排序

数据蒋堂 | “后半”有序的分组相关推荐

  1. 数据蒋堂 | 再谈有序分组

    来源:数据蒋堂 作者:蒋步星 本文长度为1200字,建议阅读2分钟 本文为你分析考虑集合的有序性,结果集的成员次序是否具有业务意义. 细心的读者可能会发现,我们在讨论有序分组时只研究了待分组集合的成员 ...

  2. 数据蒋堂 | BI系统中容易被忽视的数据源功能

    作者:蒋步星 来源:数据蒋堂 本文共1100字,建议阅读8分钟. 关注BI系统数据源有关的后台功能点. 用户在选购BI解决方案的时候,常常会更关注界面环节的功能指标,比如美观性.操作的流畅性.移动端支 ...

  3. 数据蒋堂 | 做基础软件要投入很多钱?

    作者:蒋步星 来源:数据蒋堂 本文共1100字,建议阅读8分钟. 看起来还真是,似乎还要再加大投入才行? 现在有个说法,国家对基础软硬件的投入太少,经常会说微软.Oracle.Intel这些巨头每年的 ...

  4. 数据蒋堂 | 大数据技术的4个E

    作者:蒋步星 来源:数据蒋堂 本文共1100字,建议阅读8分钟. 本文将大数据特点总结成4个E,可作为选择大数据技术解决方案的参考. 大数据的4个V说法在业界已经尽人皆知,这是指的大数据本身的特征.现 ...

  5. 数据蒋堂 | 大清单报表的打印?

    作者:蒋步星 来源:数据蒋堂 本文共900字,建议阅读5分钟. 报表打印也需要做一个缓存机制吗? 上一期文章<大清单报表应当怎么做?>中,我们谈了大清单报表的呈现方法,其实有时候这些报表还 ...

  6. 数据蒋堂 | 数据压缩手段

    作者:蒋步星 来源:数据蒋堂 本文共2600字,建议阅读9分钟.如果能物理地减少数据存储量,也就自然而然地减少了外存访问量. 我们知道,外存(硬盘)的性能远远低于内存,即使是同样复杂度的运算(CPU计 ...

  7. 数据蒋堂 | 怎样生成有关联的测试数据

    作者:蒋步星 来源:数据蒋堂 本文共1500字,建议阅读7分钟. 如何在多表情况下生成大规模测试数据时还能保证合理的关联性呢? 在向用户推荐新的数据处理技术,特别是涉及性能优化的场景时,经常会碰到生成 ...

  8. 数据蒋堂 | 内置的数据无法实现高性能

    作者:蒋步星 来源:数据蒋堂 本文共1400字,建议阅读7分钟. 获得了数据库的方便性就得不到高性能,要数据外置的高性能就要牺牲方便性. 这里说的"内", 是指数据库之内. 当数据 ...

  9. 数据蒋堂 | 报表工具的SQL植入风险

    作者:蒋步星 来源:数据蒋堂 本文共2600字,建议阅读10分钟. 报表开发人员如何规避安全漏洞问题? 所有的报表工具都会提供参数功能,主要都是用于根据用户输入的查询条件来选取合适的数据.比如希望查询 ...

最新文章

  1. Linux之重定向命令
  2. Ubuntu中安装DiscuzX2
  3. mysql的几种插入语句_Mysql 几种常见的插入 Insert into,Replace Into,Insert ignore
  4. php系统毕设答辩问题,计算机专业毕业论文答辩的一般程序及常见问题
  5. java程序的最小程序单位_微信小程序中rpx与rem单位使用
  6. wxWidgets:wxBitmapComboBox类用法
  7. VTK:PolyData之RuledSurfaceFilter
  8. POJ - 2135 Farm Tour(最小费用最大流)
  9. 不使用Vmware easy install 安装
  10. 用matlab怎么画频率特性,(matlab)频率特性仿真.pdf
  11. UTP网线和FTP网线,哪一种更适合超六类布线?
  12. VUE根据后端返回url链接下载文件
  13. tlwn726n无线网卡Linux驱动,tl-wn726n无线网卡驱动下载
  14. c 陷阱与缺陷 摘录
  15. 数值计算作业:Guass列选主元消去法解线性方程组
  16. J2SE-Java帝国的诞生
  17. C语言位运算-实现Photoshop反向功能
  18. matlab怎么把音频变成信号_利用MATLAB软件对音频信号进行频谱分析及处理.doc
  19. JS正则表达式实现简单的表单验证(账号,密码,手机号)
  20. 关于tkinter.Canvas 不显示图片的问题

热门文章

  1. 是我太天真之被BUG按在地上疯狂摩擦
  2. 阿里云API网关(8)开发指南-SDK下载
  3. Clojure世界:单元测试
  4. AC日记——中庸之道 codevs 2021
  5. _id 和 ObjectId
  6. javascript-arguments不确定参数使用
  7. 安卓安装完应用后,如何获取包的meta-inf目录下的文件?
  8. oracle存储过程dbms_output.put_line()显示打印结果
  9. 虞旦盛老师 的《数学分析续》课件
  10. Java中对HashMap的深度分析