今天优化一个存储过程,这是一个关于查询的存储过程,因为需要查询的数据比较多,所以写了存储过程,比较耗时的是1. 需要join很多表,2.需要进行多次排序计算排名,3.需要进行计算得到一些平均值,4.有个复杂的查询需要循环处理。由于做其他接口的时候意见将排名信息预先计算并保存所以第二步算是省下来了。
这个存储过程很慢,开始的时候想到可能是循环的原因,用游标做了循环。想了很久终于想到了如何用join来代替这个循环,测试后发现执行时间由原来的30s降低到了3s。这是在参数写死的情况下进行的测试,只传了一个参数,是个长度为4的字符串。但是后来用参数@xxx代替常量之后发现执行时间还是30s。刚开始没有想到是这个原因,不知道到底改了什么速度变慢了,后来发现只有这一个区别。那么如何传参数呢,传入一个NCHAR,因为长度只有4嘛,结果速度很慢。后来想到是不是跟表里面字段的类型不一样导致的,将参数类型改成varchar,执行时间果然降低。一个参数类型不一致尽然可以导致10倍的速度差异。后来写成存储过程发现速度还是慢,把参数重新赋值给临时变量后执行时间降低。看来存储过程的参数和临时变量是由差异的,这还要进一步研究。
希望可以进一步优化这个SQL,让速度更快,一个可能的方案是把算平均值的部分也独立出来,提前算好再查询。但是只为了只一件事情,又不是一个频繁执行的存储过程,似乎不太值得。