8

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

 3 years ago
source link: http://blog.chinaunix.net/uid-69903351-id-5842069.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

一、 问题背景与适用场景

在对数据集进行排序运算时,有时会遇到这样一种场景:数据集 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 脚本如下:

A 1 =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 脚本如下:

A 1 =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 亿行 Oracle 326 2556 SPL 186 1266

从测试结果看, SPL 前半有序排序与 Oracle 的大排序相比,数据量 4 亿行时,运行时间只有 60% 20 亿行时只有 50% ,可见性能提升很多,数据量越大时效果越显著。


Recommend

  • 37
    • 掘金 juejin.im 5 years ago
    • Cache

    CSS性能优化的8个技巧

    本文作者:高峰,360奇舞团前端工程师,W3C性能工作组成员,同时参与WOT工作组的学习。 我们都知道对于网站来说,性能至关重要,CSS作为页面渲染和内容展现的重要环节,影响着用户对整个网站的第一体验。因此,与其相关的性能优化是不容忽视的。 对于性能优化我们

  • 62
    • segmentfault.com 5 years ago
    • Cache

    React 性能优化技巧总结

    本文将从 render 函数的角度总结 React App 的优化技巧。需要提醒的是,文中将涉及 React 16.8.2 版本的内容(也即 Hooks),因此请至少了解 useState 以保证食用效果。 正文开始。 当我们讨论 React App 的性能问题时...

  • 9

    来源:公众号【编程珠玑】 作者:守望先生 ID:shouwangxiansheng 在分享这些性能优化技巧之前,需要说明以下几点 不要过早优化性能 现代编译器的优化能...

  • 7
    • yuanfentiank789.github.io 3 years ago
    • Cache

    Android最佳性能实践(四)——布局优化技巧

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/43376527在前面几篇文章当中,我们学习了如何通过合理管理内存,以及高性能编码技巧的方式来提升应用程序...

  • 6
    • blog.chinaunix.net 3 years ago
    • Cache

    性能优化技巧:预关联

    一、  问题背景与适用场景 SQL中JOIN的性能是个老大难问题,特别是关联表较多时,计算性能会急剧下降。 SQL实现JOIN一般是采用HASH分堆的办法,即先计算关联键的HASH值,再将相同HASH值的记录放到一起再做遍历对比。...

  • 14
    • 微信 mp.weixin.qq.com 3 years ago
    • Cache

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

    这篇文章主要参考了 Vue.js 核心成员 Guillaume Chau 在 19 年美国的 Vue conf 分享的主题:9 Performance secrets revealed,分享中提到了九个 Vue.js 性能优化的技巧。 我看完他的分享 PPT后,也阅读了相关的项目源码,在深入了解它的优化原理后...

  • 2

    一、 问题背景与适用场景 在《 性能优化技巧:小事实表与大维表关联 》中,我们尝试了小事实表与大维表关联时的性能优化方法,该方法...

  • 7

    ...

  • 5

    一、编译流程预处理:根据以字符#开头的命令,修改原始的C程序。例如:第一行中的#include xxx命令告诉预处理器要读取头文件的内容,并把它直接插入程序文本中。最终得到.i文件编译:将文本文件.i翻译成文本文件.s,它包含汇编语言程序汇...

  • 4
    • feiju12138.github.io 1 year ago
    • Cache

    【踩坑】Excl排序时报错

    【踩坑】Excl排序时报错 2022-11-04 1

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK