好久没有记录一些技术上的心得了,这两天弄了些SQL优化的,记录一下吧
1、先来一个怪问题,一个存储过程执行要2分钟,但把里面的语句复制出来只需要15秒,在网上找到了解决方法
2、索引
索引真的很重要,原先这个项目所有的表都没加索引,有些甚至没有主键,只有自增ID。加上索引后,一些列表查询明显快多了。对于两表关联、where、order by的键,一定要加索引。
如果是order by 多字段的,多字段要加上联合索引
3、分页
原先一些查询是伪分页,即查询出来所有记录,再其中挑出分页数据展示出来。
有些地方用linq的比较方便,公司框架封装了分页公共方法。有些是用存储过程,要传分页参数进去只取相应的数据。(有封装取分页数据的存储过程)
不过伪分页的性能损耗没有我想像中那么低,如果只是几百条数据,和一页20条的速度差不多,而且SqlServer没有直接像MySql那样的limit,公司封装的存储过程分页是用ROW_NUMBER,也会有一定的性能损耗。
但我还是把所有列表查询都分页了,毕竟数据越来越多时,分页还是必要的。
4、distinct
有几个查询为了去重用了这个,真是性能杀手,性能差别非常非常大,数据稍大些的都一定要避免,可以配合group、outer apply等实现。最后我改写了方法,数据一下就出来了。
5、join / left join
用join要注意,如果join不到,所有记录都会空;如果join到多条,全部记录都会多条。
join的条件可以写在on里,也可以写在where里,一般关联的那一个写在on里,其它的可写在where里,增加可读性。
6、where
先分组再where,用exists应该会比in快一些,尽量用exists吧,虽然我也没明显感觉。
7、脚本维护
不要直接在数据库里改字段或写一些配置项,建表改表、索引、存储过程、计划任务等都要写成脚本,随时都要用。不然不是忘就是错。
脚本要能反复执行,即要有IF EXISTS之类的判断,如果存在就跳过(存储过程相反,如果存在就drop了再建)。
8、时间列
datetime类型的键,重复性低,加索引好像效果不好。
我看php都是用int型的时间列,这样效果高,缺点是存取要转换。
目前项目都是datetime型,一时半会也不去动了,可以增加一列int型的,平时用datetime,要求效率时就查int型。
以前项目有两列CrTime和TrTime,用于存新增时间和修改时间,这样比较好,可以看到这条数据什么时候建的,什么时候改的,有时还会加TrMan列,还能知道谁改的。
现在项目有专门的log表,但很多都没去存,而且查起来也不方便。
9、语句优化
SQL索引能解决大部份问题,如果读写频率很高的表,可以加WITH(NOLOCK),再就是一些写法上的优化了,一条语句换个写法性能可以差好几倍。
C#性能差别最小,不管怎么写,性能都差不多,什么装箱拆箱、反射、GC等等面试调优必备,实际开发中压根就感觉不到。。。
JS主要是注意一下DOM,这个性能影响比较大,其它语句都差不多,有时代码优化了半天,也就是一个心理上的安慰,实际中一点也感觉不出来。
SQL差别最大,特别是查询,优化空间很多。因为修改删除之类,多等一会不要紧,毕竟是在操作数据,要小心些,查询不一样,多几秒就让人很不耐烦,有时也怀疑网页是不是卡死了之类又去刷新。
Linq平时CRUD还可以,碰到复杂情况性能不佳,语句也很难写,维护的人看到一大串也很头痛。
10、凑个数吧
上个月加了一些班,奖金给了1200,还不错。这个月加班更多,几乎都没周末了,不知会有多少奖金。
这几个月真的进步挺大,公司没有相应的老带新,入门相当吃力。不管技术怎么样,公司的框架和业务还是需要人指导一下的,不然就只能靠踩坑了,现在经常还能踩一些公司业务和框架上的坑。
小女儿去听力筛查,一边耳朵没通过,希望过段时间复查能通过吧,网上搜了下好像挺多人这情况的,一般都是没事,干扰因素太多。
一边耳朵能通过,至少听力系统整体没大问题,退一步说,至少不会哑。如果完全听不到,那语言能力也无法开发就糟糕了。
希望她能健健康康的成长吧
最近都在加班,没加班时也常在家写代码,没法照顾家人了,也没办法,工作就是这样,码农完全要靠技术吃饭,有多少实力拿多少钱,急不得。