查看: 10964|回复: 19

[精华] 排序原理简单说明

[复制链接]
论坛徽章:
9
会员2007贡献徽章
日期:2007-09-26 18:42:10ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44生肖徽章2007版:鸡
日期:2008-01-02 17:35:53奥运会纪念徽章:花样游泳
日期:2008-05-27 23:33:24奥运会纪念徽章:垒球
日期:2008-06-17 15:23:21奥运会纪念徽章:足球
日期:2008-07-14 17:22:53奥运会纪念徽章:跳水
日期:2008-08-06 16:18:33奥运会纪念徽章:曲棍球
日期:2008-09-11 10:05:202011新春纪念徽章
日期:2011-02-18 11:43:35
跳转到指定楼层
1#
发表于 2008-11-25 12:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
排序原理简单说明


排序原理简单说明

针对每个session,排序首先会使用内存排序(具体见数据库相关参数) ,如果不足则会使用临时表空间。但这里面又到底是怎么一个过程呢?下面阐述一下,也许对大家有用处(如果有什么不清楚或者不恰当的地方欢迎大家探讨)

假设 排序内存 = 100k,正好能盛下100条记录进行排序

当排序记录小于等于100条,ok,所有排序在内存中进行,很快

但若超过100条,则会使用临时表空间(利用磁盘进行)

1.当记录   >100  and  <10000  的时候。(100的平方)
排序会使用1倍记录大小磁盘排序。见图二。(读写次数为 :只谈临时表空间读写:写一次排序记录  读一次排序记录)

2.当>10000 and <1000000,排序会使用2倍记录大小磁盘排序(只谈临时表空间的读写 写2次排序记录 读2次排序记录,可以自己去分析,用下面的图做参考.需要费点脑细胞)


假设需要排序的记录有10010条

这个时候我们进行的排序会分为101组进行
每读100条进行一次小组排序,然后写入磁盘,第101组只有10条,排序后也写入磁盘

这是进行第二次排序,这次排序将在前100小组里面各抽取一条进行排序。《按照我个人的猜测,应该是排好后每写入一条入磁盘则将该记录所在小组重新抽取一条出来进行排序(这时是有序记录组里面所以很快)》。当这个过程完成后,这时所需要的磁盘空间大约为  实际记录存储空间的2倍(这也是多数书上提到的排序空间大约是记录空间的2倍的原因)

由于还剩下10条记录,于是这10条记录需要跟前面排序的10000条记录进行排序合并,这个代价也是相当大的!

所以,我们通常推荐,假如你需要排序的记录最大为100万条,则内存排序最小要能装下1000条,否则如上面的例子,那多余的10条,仅仅10条将会带来巨大的代价!

如果,设置的极度不合理的情况下,排序记录达到了 内存排序所能容纳的三次方以上,比如上面例子中排序需要100万记录
那么同样的,重复这个过程,当每一万条记录如上排序后,再如上从这100小组(每组10000条记录)各抽一条进行排序……

在这个过程中,磁盘的消耗和时间的代价大家都应该有个感性认识了
所以,我们建议:  内存排序 所能容纳记录数至少大于排序记录数的 平方根。一旦超过资源消耗成2的次方的提高。

以上理论可能存在出入.抛砖引玉啊.要带思考去阅读.(一家之言语)

clip_image001.jpg (13.62 KB, 下载次数: 32)

clip_image001.jpg

clip_image002.jpg (19.03 KB, 下载次数: 29)

clip_image002.jpg
论坛徽章:
233
天枰座
日期:2016-02-02 09:36:332012新春纪念徽章
日期:2012-01-04 11:49:54ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41灰彻蛋
日期:2011-06-22 19:28:30现任管理团队成员
日期:2011-05-07 01:45:082010广州亚运会纪念徽章:拳击
日期:2011-04-08 16:56:552011新春纪念徽章
日期:2011-02-18 11:43:332011新春纪念徽章
日期:2011-01-25 15:42:562011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:15
2#
发表于 2008-11-25 12:56 | 只看该作者
不过,这是oracle的?

使用道具 举报

回复
论坛徽章:
9
会员2007贡献徽章
日期:2007-09-26 18:42:10ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44生肖徽章2007版:鸡
日期:2008-01-02 17:35:53奥运会纪念徽章:花样游泳
日期:2008-05-27 23:33:24奥运会纪念徽章:垒球
日期:2008-06-17 15:23:21奥运会纪念徽章:足球
日期:2008-07-14 17:22:53奥运会纪念徽章:跳水
日期:2008-08-06 16:18:33奥运会纪念徽章:曲棍球
日期:2008-09-11 10:05:202011新春纪念徽章
日期:2011-02-18 11:43:35
3#
 楼主| 发表于 2008-11-25 13:45 | 只看该作者
差不多.理论是一样的/

使用道具 举报

回复
求职 : 数据库管理员
论坛徽章:
186
授权会员
日期:2008-07-27 22:25:202014年新春福章
日期:2014-02-18 16:42:02马上有房
日期:2014-02-18 16:42:02马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上加薪
日期:2014-02-19 11:55:14版主4段
日期:2015-02-26 02:21:03慢羊羊
日期:2015-03-04 14:51:35
4#
发表于 2008-11-25 14:07 | 只看该作者
如果能详尽的解说
快速排序原理, 冒泡排序原理, 堆排序原理, 希尔排序原理, 选择排序原理, 归并排序原理。。。。。。。
就好了

使用道具 举报

回复
论坛徽章:
9
会员2007贡献徽章
日期:2007-09-26 18:42:10ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44生肖徽章2007版:鸡
日期:2008-01-02 17:35:53奥运会纪念徽章:花样游泳
日期:2008-05-27 23:33:24奥运会纪念徽章:垒球
日期:2008-06-17 15:23:21奥运会纪念徽章:足球
日期:2008-07-14 17:22:53奥运会纪念徽章:跳水
日期:2008-08-06 16:18:33奥运会纪念徽章:曲棍球
日期:2008-09-11 10:05:202011新春纪念徽章
日期:2011-02-18 11:43:35
5#
 楼主| 发表于 2008-11-25 14:08 | 只看该作者
不懂
网络上搜索了点:
       冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,我想你是不会再无聊地把他们俩交换一下的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。

(2)选择排序

         选择排序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n-1个元素,第n个元素不用选择了,因为只剩下它一个最大的元素了。那么,在一趟选择,如果当前元素比一个元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了。比较拗口,举个例子,序列5 8 5 2 9, 我们知道第一遍选择第1个元素5会和2交换,那么原序列中2个5的相对前后顺序就被破坏了,所以选择排序不是一个稳定的排序算法。

(3)插入排序

        插入排序是在一个已经有序的小序列的基础上,一次插入一个元素。当然,刚开始这个有序的小序列只有1个元素,就是第一个元素。比较是从有序序列的末尾开始,也就是想要插入的元素和已经有序的最大者开始比起,如果比它大则直接插入在其后面,否则一直往前找直到找到它该插入的位置。如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。

(4)快速排序

       快速排序有两个方向,左边的i下标一直往右走,当a <= a[center_index],其中center_index是中枢元素的数组下标,一般取为数组第0个元素。而右边的j下标一直往左走,当a[j] > a[center_index]。如果i和j都走不动了,i <= j, 交换a和a[j],重复上面的过程,直到i>j。 交换a[j]和a[center_index],完成一趟快速排序。在中枢元素和a[j]交换的时候,很有可能把前面的元素的稳定性打乱,比如序列为 5 3 3 4 3 8 9 10 11, 现在中枢元素5和3(第5个元素,下标从1开始计)交换就会把元素3的稳定性打乱,所以快速排序是一个不稳定的排序算法,不稳定发生在中枢元素和a[j]交换的时刻。

(5)归并排序

       归并排序是把序列递归地分成短序列,递归出口是短序列只有1个元素(认为直接有序)或者2个序列(1次比较和交换),然后把各个有序的段序列合并成一个有序的长序列,不断合并直到原序列全部排好序。可以发现,在1个或2个元素时,1个元素不会交换,2个元素如果大小相等也没有人故意交换,这不会破坏稳定性。那么,在短的有序序列合并的过程中,稳定是是否受到破坏?没有,合并过程中我们可以保证如果两个当前元素相等时,我们把处在前面的序列的元素保存在结果序列的前面,这样就保证了稳定性。所以,归并排序也是稳定的排序算法。

(6)基数排序

      基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序,最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。基数排序基于分别排序,分别收集,所以其是稳定的排序算法。

(7)希尔排序(shell)

       希尔排序是按照不同步长对元素进行插入排序,当刚开始元素很无序的时候,步长最大,所以插入排序的元素个数很少,速度很快;当元素基本有序了,步长很小,插入排序对于有序的序列效率很高。所以,希尔排序的时间复杂度会比o(n^2)好一些。由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的。

(8)堆排序

      我们知道堆的结构是节点i的孩子为2*i和2*i+1节点,大顶堆要求父节点大于等于其2个子节点,小顶堆要求父节点小于等于其2个子节点。在一个长为n的序列,堆排序的过程是从第n/2开始和其子节点共3个值选择最大(大顶堆)或者最小(小顶堆),这3个元素之间的选择当然不会破坏稳定性。但当为n/2-1, n/2-2, ...1这些个父节点选择元素时,就会破坏稳定性。有可能第n/2个父节点交换把后面一个元素交换过去了,而第n/2-1个父节点把后面一个相同的元素没有交换,那么这2个相同的元素之间的稳定性就被破坏了。所以,堆排序不是稳定的排序算法。

综上,得出结论: 选择排序、快速排序、希尔排序、堆排序是不稳定的排序算法,而冒泡排序、插入排序、归并排序和基数排序是稳定的排序算法。

[ 本帖最后由 tanfufa 于 2008-11-25 14:12 编辑 ]

使用道具 举报

回复
论坛徽章:
3
八级虎吧徽章
日期:2008-12-17 17:53:09CTO参与奖
日期:2009-02-20 09:44:20授权会员
日期:2009-03-06 12:50:31
6#
发表于 2008-11-26 08:30 | 只看该作者
路过,学习中.....

使用道具 举报

回复
招聘 : Linux运维
论坛徽章:
235
紫蜘蛛
日期:2007-09-26 17:05:46玉兔
日期:2007-09-26 17:05:05现任管理团队成员
日期:2011-05-07 01:45:08玉兔
日期:2006-08-29 20:38:48紫蜘蛛
日期:2007-09-26 17:05:34阿斯顿马丁
日期:2013-11-19 10:38:16奔驰
日期:2013-10-16 09:08:58红旗
日期:2014-01-09 11:57:39路虎
日期:2013-08-13 14:52:35林肯
日期:2015-05-19 13:01:16
7#
发表于 2008-11-26 08:35 | 只看该作者
不错,学习~!

使用道具 举报

回复
论坛徽章:
5
生肖徽章2007版:鼠
日期:2008-01-02 17:35:53生肖徽章2007版:鼠
日期:2008-01-02 17:35:53奥运会纪念徽章:体操
日期:2008-10-24 13:08:31
8#
发表于 2008-11-26 09:27 | 只看该作者
不错,学习~!

使用道具 举报

回复
求职 : 数据库开发
论坛徽章:
59
妮可·罗宾
日期:2017-04-29 10:55:21弗兰奇
日期:2018-08-31 20:09:41ITPUB18周年纪念章
日期:2019-03-12 14:03:4619周年集字徽章-周
日期:2019-09-29 10:43:3420周年集字徽章-20	
日期:2020-10-28 14:48:18
9#
发表于 2008-11-26 15:03 | 只看该作者
那么如何能够得知在db2或oracle中内存排序中是否能装下1000条呢?

使用道具 举报

回复
论坛徽章:
9
会员2007贡献徽章
日期:2007-09-26 18:42:10ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44生肖徽章2007版:鸡
日期:2008-01-02 17:35:53奥运会纪念徽章:花样游泳
日期:2008-05-27 23:33:24奥运会纪念徽章:垒球
日期:2008-06-17 15:23:21奥运会纪念徽章:足球
日期:2008-07-14 17:22:53奥运会纪念徽章:跳水
日期:2008-08-06 16:18:33奥运会纪念徽章:曲棍球
日期:2008-09-11 10:05:202011新春纪念徽章
日期:2011-02-18 11:43:35
10#
 楼主| 发表于 2008-11-26 17:41 | 只看该作者
Sort heap thres for shared sorts (4KB) (SHEAPTHRES_SHR) = AUTOMATIC
Sort list heap (4KB)                         (SORTHEAP) = AUTOMATIC
orac le  也有同样的参数. 
sort_area_size                       integer     65536
SQL>  

oracle 10以后.都自动了.如果需要手动 修改 
workarea_size_policy=manual

跟db2 9一样也可以自动手动.
然后计算一下就可以.

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表