性能优化技巧:前半有序时的排序

一、  问题背景与适用场景在对数据集进行排序运算时,有时会遇到这样一种场景:数据集T已经按字段a有序,而字段b无序,现在我们要将T按a、b排序,我们称之为前半有序(a有序)的排序。此时我们能想到一种优化的排序方法:从T中先取出a值相同的一组记录,再这一组内对b排序。然后再依次取出下一组a值相同的记录,重复这个动作,直到完成T中所有记录的排序。这种方法的好处是不需要对T中所有记录进行大排序,一次只需取出一小组,对内存容量要求大大减低,只需能装下每个小组即可。遗憾的是SQL并不支持这种优化算法,只能所有记录进行大排序,而SPL提供了对这种算法的支持,下面我们实例测试一下,并与Oracle作对比。二、  测试环境与任务测试机有两个Intel2670 CPU,主频2.6G,共16核,内存64G,SSD固态硬盘。在此机上安装虚拟机来测试,设置虚拟机为16核、8G内存。在虚拟机上创建数据表salesman1,共两个字段:area(字符串)、salesman(字符串),生成数据记录4亿行,按area升序排列,area不同值共2000个,每个area对应salesman为20万个。将此表数据导入Oracle数据库,同时用它生成集算器SPL组表来进行测试。再建另一张表salesman2作大数据量测试,数据表结构不变,总数据记录20亿行,area值4000个,每个area对应50万个salesman。测试任务都是要对表按照area、salesman排序。三、  小数据量测试1.  Oracle测试编写测试SQL如下:select area, salesman from salesman1 order by area, salesman本来只需这一句简单的SQL即可,不过这个排序结果的输出时间却非常长,为了减少输出量,只统计排序过程的用时,我们不输出排序后的全部结果,而只输出中间位置的一行,也就是行号为2亿的那一行,所以SQL语句改写如下:select area, salesman from (select area, salesman, rownum rn from (select area, salesman from salesman1 order by area, salesman)) where rn=200000000;要多说一句,这个查询其实没有什么业务意义,纯粹是为了迫使数据库大排序且避免统计输出时间的 。2.  SPL测试编写SPL脚本如下:

A1=now()2=file("/home/ctx/salesman1.ctx").create().cursor(area,salesman)3=A2.group@qs(area;salesman)4=A3.skip(199999999)5=A3.fetch(1)6=interval@s(A1,now())group@qs中选项s表示对数据集只排序,不分组;选项q表示数据集对分号前的分组表达式(area)是有序的,请求使用前半有序时的排序方法按分号后的表达式(salesman)排序。四、  大数据量测试1.  Oracle测试编写测试SQL如下:select area, salesman from (select area, salesman, rownum rn from (select area, salesman from salesman2 order by area, salesman)) where rn=1000000000;输出行号为10亿的一行。2.  SPL测试编写SPL脚本如下:

A1=now()2=file("/home/ctx/salesman2.ctx").create().cursor(area,salesman)3=A2.group@qs(area;salesman)4=A3.skip(999999999)5=A3.fetch(1)6=interval@s(A1,now())五、  测试结果测试结果如下,单位(秒):数据量4亿行20亿行Oracle3262556SPL1861266从测试结果看,SPL前半有序排序与Oracle的大排序相比,数据量4亿行时,运行时间只有60%,20亿行时只有50%,可见性能提升很多,数据量越大时效果越显著。

(0)

相关推荐

  • Oracle外部表详解

    外部表概述 外部表只能在Oracle 9i之后来使用.简单地说,外部表,是指不存在于数据库中的表.通过向Oracle提供描述外部表的元数据,我们可以把一个操作系统文件当成一个只读的数据库表,就像这些数 ...

  • 性能优化技巧:后半有序分组

    一.  问题背景与适用场景什么是后半有序?如果数据集T已经按字段a.b有序,现在我们要将T按b排序或分组时,因为在a值相同的段内,b都是有序的,这种要排序或分组的字段在分段内有序的情况就称为后半有序. ...

  • 性能优化技巧:维表过滤或计算时的关联

    在事实表与维表的关联查询时,常常会遇到需要对维表的数据进行过滤或者针对维表做计算的情况,这时可以有两种处理方式:1.先做关联(如果是内存则可以是预关联),再对关联后的事实表进行过滤.就象在<性能 ...

  • 揭秘 Vue.js 九个性能优化技巧

    这篇文章主要参考了 Vue.js 核心成员 Guillaume Chau 在 19 年美国的 Vue conf 分享的主题:9 Performance secrets revealed,分享中提到了九 ...

  • 性能优化技巧:有序分组

    一.  问题背景与适用场景通常分组计算都采用hash方案,即先计算分组字段的hash值,hash值相同的记录被分拣到一个小集合里,然后在这个小集合中遍历找分组字段值相同的聚合成一组.分组的复杂度(比较 ...

  • 性能优化技巧:大事实表与大维表关联

    一.  问题背景与适用场景在<性能优化技巧:小事实表与大维表关联>中,我们尝试了小事实表与大维表关联时的性能优化方法,该方法利用了小事实表可以装入内存的特点,将关联键汇集排序后到大维表中查 ...

  • 性能优化技巧:小事实表与大维表关联

    一.  问题背景与适用场景在主子表关联查询中,有时会遇到这样一种情况:按条件过滤后的事实表数据量很小,能够全部装载进内存或仅比内存略大一点:而要关联的维表数据量很大,比内存要大很多.这种时候,如果维表 ...

  • 性能优化技巧:附表

    一.  问题背景与适用场景在<性能优化技巧:有序归并>中我们见证了有序归并算法提升主子表的关联性能,在集算器中,还有进一步提高性能的办法-附表.集算器组表支持主子表保存在同一文件中,先用主 ...

  • 性能优化技巧:外键序号化

    一.  问题背景与适用场景在<性能优化技巧:部分预关联>一文中,我们介绍了将维表内存化并预关联的技术,但事实表与维表关联时,仍需进行hash计算和比对,怎么提高这一步的性能呢?我们今天再介 ...

  • 性能优化技巧:部分预关联

    一.  问题背景与适用场景在<性能优化技巧:预关联>中,我们测试了将数据表事先全部加载进内存并做好关联后的查询性能优化问题,但如果内存不够大,不能将维表和事实表全部装入,那怎么办呢?此时, ...