谁说游标一定慢?

原创 2005年12月31日 10:03:00

昨天在SQL Server版面上遇到了这样的一个问题:

有一个表如下:
CREATE TABLE [#tmp](px int IDENTITY(1,1),value int)
大约有10000条记录,value 字段是一个随机的值,现要求是输入的一个值M,要找出前N条记录,且N条记录value的总和刚好不大M(意思是再多一条记录都会大于M)。

要求:语句运行时间要求在1秒种内完成

说明:
px值小的认为是排在px大的前面,可以用存领储过程、函数 

示例数据为:
px   value
----------
5    5
4    12
7    9
1    3
3    6
6    23
2    15

则,录入20,找出:
px   value
----------
1    3
2    15


1、
最初打算用最常规的方法来实现这个需求,但是不考虑效率方面的要求:

select a.* from #tmp a where (select sum(value) from #tmp where px<=a.px)<=@m

结果在10,000条测试数据的压力测试下,整个查询历时41s,与效率要求相去甚远


2、
于是,转而通过遍历表的方式实现查询:

declare @px int,@s bigint,@m int
set @s=0
set @m=20

update a
set
    @px=case when @s<=@m then px else @px end,
    @s =@s+value
from
    #t1 a

select * from #t1 where px<@px order by px

在100,000条测试数据的情况下,效率基本满意,但是又出现了新的问题,一旦px字段不是按升序排列,查询的结果就不正确

3、
与pbsql(风云)君子所见略同,决定用游标

declare @px int,@value int,@sum int,@m int,@px1 int
set @sum=0
set @m=20

declare t_cursor cursor for select px,value from #tmp order by px

open t_cursor
fetch next from t_cursor into @px,@value

while @@fetch_status=0
begin
    if(@sum>@m)
        break
    set @sum=@sum+@value
    set @px1=@px
    fetch next from t_cursor into @px,@value
end
close t_cursor
deallocate t_cursor

select * from #tmp where px<@px1 order by px

效率可以到达要求,原以为万事大吉,结果提问者认为游标慢,要求不用游标

4、
最后,好汉只能下猛料了

declare @px int,@s int,@m int
set @s=0
set @m=20

select
    @px=case when @s<=@m then px else @px end,
    @s =@s+case when @s<=@m then value else 0 end
from
    (select top 100 percent * from #tmp order by px) a

select * from #tmp where px<@px order by px


总结:
1、对于某些特殊的查询,不能单纯为了图SQL语句简单直观,不能认为简单就效率高,简单就是美,其实查询不是那么简单
2、不要固执的认为游标慢,当然,在与select * from tab where ...等诸多情况比较,游标遍历表确实是效率低一些,然而有些时候,游标的效率不是我们想象中那么差劲的,就比如这

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

为认识8周年点赞、谁说男女间没有纯洁的友谊

我敬爱的朋友这周末就是你的生日的了,去年的生日因为家里有事,我没能去,算起来我们已经整整有一年3个月没有见了,有一年多没有聊过天,但是我相信我们的友谊是长存的【谁说男女之间没有纯洁的友谊!】 我和Li...
  • wgbhl
  • wgbhl
  • 2015-08-28 16:24
  • 318

2011中国编程者=走出程序员的悲哀=谁说中国程序员只能吃青春饭?

首先我想说的是,如何选择编程语言,在做出选择前,我们要先了解各种语言的优缺点:   编译型的语言:        ASM:    汇编语言,几乎接近机...
  • yhxjc
  • yhxjc
  • 2011-06-10 11:31
  • 1038

是谁说 JavaScript 简单的?

js小bug

一个有趣的C语言程序,谁说程序员不懂浪漫

浏览看雪论坛,发现有人讲了一个有趣的C语言程序。原帖地址:http://bbs.pediy.com/showthread.php?p=389887我做了一点点的修改,最后打印出 i O y(中间那个是...

“父亲节”为程序员正名:谁说程序员不会表达爱?

在大多数人的认知里,程序员的代名词就是呆板、木讷,不善交际,不懂浪漫,和文人骚客、文艺青年是截然相反的一个群体。       事实是这样吗?程序员们,你认同上面的说法吗?       你看...

“父亲节”为程序员正名——谁说程序员不会表达爱?

在大多数人的认知里,程序员的代名词就是呆板、木讷,不善交际,不懂浪漫,和文人骚客、文艺青年是截然相反的一个群体。       事实是这样吗?程序员们,你认同上面的说法吗?       你看...

谁说开源不能赚钱?

原文链接:http://www.linux-foundation.org/weblogs/jzemlin/2011/06/30/who-says-you-can%E2%80%99t-make-mone...

android studio最简单的更新方式(像普通软件一样直接在线升级,谁说as不能在线升级的???)

本文转自:http://android-mirror.bugly.qq.com:8080/include/usage.html 之前一直看诸位网友说as不可直接在线更新,于是耐心琢磨,google官网...

谁说Java代码多,5分钟搞定App缓存

概述:我用了5分钟为自己的App(应用程序)添加缓存,再一次证明Java也不需要写长篇的代码,就能为App添加缓存。想知道我怎样做的吗?请看下文。

腾讯帝国15年争霸之路:谁说我只会抄袭,不会创新?

1,QQ是如何打败ICQ的? 1996年,ICQ诞生,瞬间风靡全球,到1998年的时候,这款软件已经垄断了中国的即时通讯市场。而在这一年,ICQ嫁入豪门,成为美国最大的互联网集团AOL公司的旗下...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)