新足迹

 找回密码
 注册

精华好帖回顾

· 双职工家庭的福音之九适合孕妇的松仁玉米 (2005-5-6) binbingogo · 爸爸菜谱 - “大兴”鱼头汤 (2008-11-21) patrickzhu
· 参加活动 - 小L的2010年度总结 (内有多图,终于填坑完毕) (2010-12-19) 旋木 · 小鸟流水账之Great Barrier Reef, Queensland 2009 (更新完毕) (2009-3-29) 棉被
Advertisement
Advertisement
楼主:澳贼

谁懂 database tuning [复制链接]

发表于 2011-1-24 11:56 |显示全部楼层
此文章由 乱码 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 乱码 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 bffbffbff 于 2011-1-24 12:37 发表


我遇到用curosr的情况与表的大小倒没直接关系,经常是需要对loop里面的每一row数据进行比较复杂的运算或者逻辑

还有几次见到复杂的cursor甚至跨越了多个trigger 基本上当成是temp table用了


你可以用case when的结构在where中,logic来说是简单些,也显得比较高深 但看它的execution plan,scan table是一定的,不到万不得已,不推荐用。

(case when... then 1 else..then 2 end)=1 这种形式
Advertisement
Advertisement

参与宝库编辑功臣

发表于 2011-1-24 12:10 |显示全部楼层
此文章由 bffbffbff 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 bffbffbff 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 乱码 于 2011-1-24 12:56 发表


你可以用case when的结构在where中,logic来说是简单些,也显得比较高深 但看它的execution plan,scan table是一定的,不到万不得已,不推荐用。

(case when... then 1 else..then 2 end)=1 这种形式


, 试过了,有时候还是搞不定

举个例子说吧,比如说loop through一个不大的表(可以是1-20条记录不等),然后根据每个row里面的几个field值来决定什么样的一行记录去insert到temp/table variable里,最终形成的temp table用于下一步运算。

我能想到过的我的问题是
1. 有时候当前记录如果不符合条件剩下的rows就不需要处理了直接break
2,有时候当前记录和前一条记录需要有比较或者需要前面记录里的值。
3. 有时候当前记录可能需要slip掉进入下一个记录
永远的junior programmer

发表于 2011-1-24 12:18 |显示全部楼层
此文章由 IsDonIsGood 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 IsDonIsGood 所有!转贴必须注明作者、出处和本声明,并保持内容完整
但凡需要将business logic写进sp的时候,都会遇到不得不用cursor或者while的时候,
我的选择是将尽量少的数据写进temp table,然后再temp 表内 cursor或者loop。
写过最麻烦的一个要比较previous row ,current row ,next row的所有值来确定mapping rule,实在没办法,只能用loop来实现,5分钟一次的schedule,运行还好,基本上20s内完成。

不得不loop的时候个人经验是尽量减小loop的表容量,如果实在减少不了,应该考虑将businiess logic 写到application而不是db里去

评分

参与人数 1积分 +3 收起 理由
+ 3 我很赞同

查看全部评分

发表于 2011-1-24 12:20 |显示全部楼层
此文章由 IsDonIsGood 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 IsDonIsGood 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 乱码 于 2011-1-24 12:56 发表


你可以用case when的结构在where中,logic来说是简单些,也显得比较高深 但看它的execution plan,scan table是一定的,不到万不得已,不推荐用。

(case when... then 1 else..then 2 end)=1 这种形式

case 的cost应该也不低吧,尤其是在where 里,而且稍微复杂点的logic用case写不加comment的话很难读。

参与宝库编辑功臣

发表于 2011-1-24 12:22 |显示全部楼层
此文章由 bffbffbff 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 bffbffbff 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 IsDonIsGood 于 2011-1-24 13:18 发表
但凡需要将business logic写进sp的时候,都会遇到不得不用cursor或者while的时候,
我的选择是将尽量少的数据写进temp table,然后再temp 表内 cursor或者loop。
写过最麻烦的一个要比较previous row ,current row ,next r ...


很同意, 现在我一旦遇到非用cursor的不可的时候,就尽量减少所选数据数量。
只是见网上很多人讨论cursor的alternatives,而且发现这些方案真的把大多数cursor给取代了, 所以在这里就想问问大伙能否把这个也解决了。

当然,cursor的东西确实不易做很频繁使用的scheduled job

[ 本帖最后由 bffbffbff 于 2011-1-24 13:24 编辑 ]
永远的junior programmer

参与宝库编辑功臣

发表于 2011-1-24 12:25 |显示全部楼层
此文章由 bffbffbff 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 bffbffbff 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 IsDonIsGood 于 2011-1-24 13:20 发表

case 的cost应该也不低吧,尤其是在where 里,而且稍微复杂点的logic用case写不加comment的话很难读。


难度是一方面,主要还是觉得case搞不定所有cursor能做的东西
永远的junior programmer
Advertisement
Advertisement

发表于 2011-1-24 12:38 |显示全部楼层
此文章由 IsDonIsGood 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 IsDonIsGood 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 bffbffbff 于 2011-1-24 13:25 发表


难度是一方面,主要还是觉得case搞不定所有cursor能做的东西

稍微复杂点的business logic case就不行了,个人感觉一旦 case嵌套了2层以上判断 performance就会有影响。case也就做做简单的判断还可以,cursor/while实现business logic的能力还是很强的,就是cost太高。不过个人意见是小数量data loop还素很快的,没什么performance issue。
不过我的经验是sql server的,不知道Oracle怎样,感觉上oracle 的cursor 功能更强大?performance呢?呼Oracle大侠们现身说法~~~
刚开始用case的时候经常忘记指定所有的条件,然后就返回一大串NULL,当时那个郁闷啊~~~
另:楼上能给个cursor的替代例子么?谢啦~~

发表于 2011-1-24 12:58 |显示全部楼层
此文章由 乱码 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 乱码 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 IsDonIsGood 于 2011-1-24 13:18 发表
但凡需要将business logic写进sp的时候,都会遇到不得不用cursor或者while的时候,
我的选择是将尽量少的数据写进temp table,然后再temp 表内 cursor或者loop。
写过最麻烦的一个要比较previous row ,current row ,next r ...


如果是牵扯到previous/next row,最好用cte sort一下,出rownumber,然后用两个/多个table instance,在where中用table1.rownumber=table2.rownumber+1,这种形式.

把需要计算的condition写到where中,一定会引起table scan,不光是case when, 所以design很重要,design阶段不能解决的,才考虑把business logic 放到where中,但performance wise,的确不推荐。

评分

参与人数 2积分 +5 收起 理由
bffbffbff + 2
IsDonIsGood + 3 感谢分享

查看全部评分

参与宝库编辑功臣

发表于 2011-1-24 13:11 |显示全部楼层
此文章由 bffbffbff 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 bffbffbff 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 IsDonIsGood 于 2011-1-24 13:38 发表

稍微复杂点的business logic case就不行了,个人感觉一旦 case嵌套了2层以上判断 performance就会有影响。case也就做做简单的判断还可以,cursor/while实现business logic的能力还是很强的,就是cost太高。不过个人意见是 ...


简单点的string concatenation 比如说建立个dynamic query 来create,insert或者query table之类的 可以
select @sql = @sql + a.col from a
就是实现了,偶尔借助点case就可以把很多简单的cursor 搞定
稍微有点计算或者逻辑的可以用 UDF 写好。
还有就像乱码兄说的可以用cte+rownumber搞定,可惜我学了这招之后几次试图用但由于我遇到的情况不太一样所以用不上

评分

参与人数 1积分 +3 收起 理由
IsDonIsGood + 3 谢谢奉献

查看全部评分

永远的junior programmer

发表于 2011-1-24 13:36 |显示全部楼层

回复 39# 的帖子

此文章由 IsDonIsGood 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 IsDonIsGood 所有!转贴必须注明作者、出处和本声明,并保持内容完整
之前都没怎么用CTE,看来要好好学一学了。
有没有链接一观?hoho,懒得放狗了~~

参与宝库编辑功臣

发表于 2011-1-24 13:44 |显示全部楼层
此文章由 bffbffbff 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 bffbffbff 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 IsDonIsGood 于 2011-1-24 14:36 发表
之前都没怎么用CTE,看来要好好学一学了。
有没有链接一观?hoho,懒得放狗了~~


CTE可是好东西啊,有问题你抓CTE专家乱码兄一顿狂问就可以了

http://msdn.microsoft.com/en-us/library/ms190766.aspx
永远的junior programmer
Advertisement
Advertisement

发表于 2011-1-24 13:45 |显示全部楼层
此文章由 老衲 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 老衲 所有!转贴必须注明作者、出处和本声明,并保持内容完整
对net developer来说,Per Tuning这个提法可能太大。看过一篇文章,觉得很不错,如果都能理解,对net developer来说应该足够了。

SQL Server DO's and DONT's
http://www.codeproject.com/KB/database/sqldodont.aspx
头像被屏蔽

禁止发言

发表于 2011-1-24 13:53 |显示全部楼层
此文章由 澳贼 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 澳贼 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 老衲 于 2011-1-24 14:45 发表
对net developer来说,Per Tuning这个提法可能太大。看过一篇文章,觉得很不错,如果都能理解,对net developer来说应该足够了。

SQL Server DO's and DONT's
http://www.codeproject.com/KB/database/sqldodont.aspx


谢谢长老。 您就的这片如何?
http://www.databasejournal.com/f ... rver-Developers.htm
签名被屏蔽

发表于 2011-1-24 14:00 |显示全部楼层