楼主: shift

[精华] 谁提供的排序算法最优?

[复制链接]
论坛徽章:
86
ITPUB元老
日期:2005-02-28 12:57:002012新春纪念徽章
日期:2012-01-04 11:49:542012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20咸鸭蛋
日期:2012-05-08 10:27:19版主8段
日期:2012-05-15 15:24:112013年新春福章
日期:2013-02-25 14:51:24
21#
发表于 2003-3-13 09:36 | 只看该作者

en

还是你这个简单些  

不知道效率是不是有折扣

使用道具 举报

回复
论坛徽章:
69
生肖徽章2007版:羊
日期:2008-11-14 14:42:19复活蛋
日期:2011-08-06 08:59:05ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:542012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20版主4段
日期:2012-05-15 15:24:11
22#
发表于 2003-3-13 09:39 | 只看该作者
我想与在PL SQL代码中实现比较是不会降低效率的。

使用道具 举报

回复
论坛徽章:
6
ITPUB元老
日期:2005-02-28 12:57:00授权会员
日期:2005-11-04 13:13:52会员2006贡献徽章
日期:2006-04-17 13:46:34在线时间
日期:2006-12-24 04:01:01会员2007贡献徽章
日期:2007-09-26 18:42:10ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41
23#
发表于 2003-3-13 09:40 | 只看该作者

Re: o,

最初由 biti_rainy 发布
[B]declare
btw: 关于 oracle8i personal edition release 8.1.6.0.0.
看你的 compatible 修改为 8.1.6 以上跟你的真实版本一致 [/B]

收到.我修改compatible ,再试一下.
谢谢.

使用道具 举报

回复
论坛徽章:
86
ITPUB元老
日期:2005-02-28 12:57:002012新春纪念徽章
日期:2012-01-04 11:49:542012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20咸鸭蛋
日期:2012-05-08 10:27:19版主8段
日期:2012-05-15 15:24:112013年新春福章
日期:2013-02-25 14:51:24
24#
发表于 2003-3-13 09:42 | 只看该作者

我不确信的一点

就是 group by 本身的结果是排序后剔除重复记录,结果本身是有序的

按照oracle 的如今的优化器,应该不会再重复的进行 排序了

这样的话应该没什么问题

只是我没有测试确认,但如果需要进行2次排序,假设数据量大了,和数据量小的时候比较,差异可不是一般的大了 ,你说呢?

使用道具 举报

回复
论坛徽章:
6
ITPUB元老
日期:2005-02-28 12:57:00授权会员
日期:2005-11-04 13:13:52会员2006贡献徽章
日期:2006-04-17 13:46:34在线时间
日期:2006-12-24 04:01:01会员2007贡献徽章
日期:2007-09-26 18:42:10ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41
25#
发表于 2003-3-13 09:56 | 只看该作者

to biti

我已经改了参数.但还是不行.我估计是personal不支持了.
SQL> show parameters compa

NAME                                 TYPE    VALUE
------------------------------------ ------- ------------------------------
compatible                           string  8.1.6
plsql_v2_compatibility               boolean FALSE
SQL> update test set o =
  2  (select tmp.rn from
  3  (select rowid rid,row_number() over (order by v desc) rn from test) tmp
  4  where test.rowid = tmp.rid);
update test set o =
*
ERROR at line 1:
ORA-00439: feature not enabled: OLAP Window Functions

使用道具 举报

回复
论坛徽章:
63
版主7段
日期:2012-05-15 15:24:11itpub13周年纪念徽章
日期:2014-10-08 15:16:50itpub13周年纪念徽章
日期:2014-10-08 15:16:50itpub13周年纪念徽章
日期:2014-10-08 15:16:50itpub13周年纪念徽章
日期:2014-10-10 14:34:59马上加薪
日期:2015-01-08 15:39:192015年新春福章
日期:2015-03-04 14:19:112015年新春福章
日期:2015-03-06 11:57:31
26#
发表于 2003-3-13 10:00 | 只看该作者

817 IS OK,难道816不支持?

SQL> update test set c =  (select tmp.rn from
  2   (select rowid rid,row_number() over (order by a desc) rn from test) tmp);

已更新0行。

SQL> show parameters compa

NAME                                 TYPE    VALUE
------------------------------------ ------- ------------------------------
compatible                           string  8.1.0
plsql_v2_compatibility               boolean FALSE

使用道具 举报

回复
论坛徽章:
69
生肖徽章2007版:羊
日期:2008-11-14 14:42:19复活蛋
日期:2011-08-06 08:59:05ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:542012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20版主4段
日期:2012-05-15 15:24:11
27#
发表于 2003-3-13 10:03 | 只看该作者

Re: 我不确信的一点

最初由 biti_rainy 发布
[B]就是 group by 本身的结果是排序后剔除重复记录,结果本身是有序的

按照oracle 的如今的优化器,应该不会再重复的进行 排序了

这样的话应该没什么问题

只是我没有测试确认,但如果需要进行2次排序,假设数据量大了,和数据量小的时候比较,差异可不是一般的大了 ,你说呢? [/B]

执行计划表明只做一次sort(group by),而且我也认为oracle不可能这么差!

使用道具 举报

回复
论坛徽章:
0
28#
 楼主| 发表于 2003-3-13 15:03 | 只看该作者

小结一下

首选感谢nyfor写出的精采代码。
高手的语言就是如此简练!
简单最美!
----------------------------------------------------------------------------------
declare
i integer := 1;
begin
for c in (select v from test group by v order by v desc) loop
update test set o = i where v = c.v;
i := i + 1;
end loop;
end;
----------------------------------------------------------------------------------
上面nyfor写的代码已经过本人测试,可在低版本oracle中执行,可应付相同数的问题,简明易读,可以说是比较完美的。

在数据量大的情况下如何呢?我建了一个有三万多记录的表:
SQL> desc test1
列名...........................可空值否...类型
------------------------------- -------- ----
BYSJ.......................... NUMBER(10,2)
BJSJ...........................NUMBER(10,2)
SQL> set timing on
SQL> select count(*) from test1;

COUNT(*)
---------
    31790
实际(值):50

SQL> declare
  2  i number := 1;
  3  begin
  4  for c in (select bysj from test1 group by bysj order by bysj desc) loop
  5  update test1 set bjsj = i where bysj = c.bysj;
  6  i := i + 1;
  7  end loop;
  8  end;
  9  /

PL/SQL过程完全成功.

实际(值):2879140
-----------------------------------------------------------------------------------
环境:
SQL*Plus: Release 3.3.4.0.0
PL/SQL Release 8.0.6.0.0
表没有索引

我也不清楚2879140值转换成分钟有多少, 大概有一个多小时

如果记录数是5000条,不到二分钟(实际(值):115450)
如果记录数是999条,(integer能接受的最大值),则只有几秒钟!(实际(值):4290)

结论是记录数小于1000条,这是非常好的方法,记录数大于10000就要考虑怎样进行优化了。

当然我们的oracle版本太低,希望用高版本的朋友测一下大数据量执行情况。

再次感谢 nyfor !及各位DX!

使用道具 举报

回复
论坛徽章:
86
ITPUB元老
日期:2005-02-28 12:57:002012新春纪念徽章
日期:2012-01-04 11:49:542012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20咸鸭蛋
日期:2012-05-08 10:27:19版主8段
日期:2012-05-15 15:24:112013年新春福章
日期:2013-02-25 14:51:24
29#
发表于 2003-3-13 15:17 | 只看该作者

几点建议

用 dbms_sql 包执行 :  
alter session set sort_area_size = 10240000;

先在 v 上建立索引,完毕再删除索引,如果允许存在索引那更好

或者尝试
for c in (select /*+ first_rows */v from test group by v order by v desc) loop
for c in (select /*+ all_rows */v from test group by v order by v desc) loop

不知道有没有效果

使用道具 举报

回复
论坛徽章:
69
生肖徽章2007版:羊
日期:2008-11-14 14:42:19复活蛋
日期:2011-08-06 08:59:05ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:542012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20版主4段
日期:2012-05-15 15:24:11
30#
发表于 2003-3-13 15:32 | 只看该作者
要是updatable view允许使用表达式伪列等那就会比较快,而且SQL简单!
如:
update (select o,dense_rank() over (order by v desc) rank from test)
set o = rank;

可惜这个语句不能执行,因为里边含有dense_rank()这样的函数表达式

使用道具 举报

回复

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

本版积分规则 发表回复

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