存储过程性能优化

近期为某项目组写存储过程进行一些较为复杂的计算。存储过程,在性能上,主要是节省了编译的时间,除此而外,似乎并没有什么优势。相反,它语法比较弱,写起来不够方便,甚至对面向过程编程也支持得很不好。

所以在写这些存储过程的时候,我一度想写成CLR存储过程。

我写的这些存储过程,是根据别人给出的算法(伪码)来写的,里面有两个嵌套的循环,共计80万次循环。循环里面有计算、查找各种参数表。最后将结果保存到结果表。

刚开始的时候,因为计算非常复杂,业务也不熟,只能机械地按照算法描述,一步一步地来,最多将一些共用的计算,提出循环外,结果好不容易出来一个存储过程,执行一次居然要20分钟!

我靠,我在简历上总是吹嘘自己擅长性能优化,结果就出来这么个东西,狠狠滴扇了自己一记耳光。

后来

1、尽量用一些SQL语句来代替一些小循环,比如用上聚合函数、求平均函数,时间缩短到10分钟

2、不再亦步亦趋地按照算法描述,以致将一条长达100个字段的记录分90次来更新,而是采用拼凑语句,将更新语句在循环中拼凑后,再统一更新。时间缩短到5分钟左右。

3、其他就是中间结果存放于临时表,加索引;用sp_executesql来替换exec等,时间略微缩短了些,但不是很明显

4、后来发现,有很大一部分时间耗在循环里面的查找语句上。有些存储过程内层循环(9K次)不必查找参数表,结果时间一下缩短到2分钟左右,起码少了一半。

5、其实这个查找参数表,我已经在循环外面查找出该条记录,但该记录有100个字段,要根据条件找出相应的字段。本来以为应该很快,就一条记录而已,现在看来,字段多的话,也是要消耗不少时间的。于是修改算法,尽量将100列转成2个字段,100行的表,结果时间也得以大幅改善。

总结:

1、尽量避免循环,尽量发挥SQL的优势,用SQL语句,比如说表关联、聚合来代替循环;

2、查找语句要花不少时间,尽量不要放在循环内;

3、字段太多的查找,就算只有一条记录,还不如转成多条记录,很少字段,建了索引的临时表。




原文地址:https://www.cnblogs.com/leftfist/p/4257926.html