.Net SQL调优
客户端代码优化
使用Any()代替Count()>0
Count代替Count()
如果集合实现ICollection,如List,Count属性可直接得出结果而不用遍历。
linq语句left join 代替select嵌套子查询
select嵌套子查询容易生成遍历sql
减少访问数据库的次数
相同或类似语句的多次执行,考虑一次查出放入内存,或将经常访问的数据放缓存
使用async/await语法提高吞吐量,异步查询多条sql
Parallel.ForEach并行查询
杜绝不必要的子查询和连接表
过多的类型转换应统一类型
操作符优化
exists和not exists代替in, not in
大数据量的表中推荐用 exists 代替 in,not in 不走索引,可以用 not exists 代替。
ORM中使用any()生成exist语句
为is null,is not null设置默认值
索引是不索引空值的,推荐字段设置默认值,例如:int = 0,string =''
!= 改为 > or <
不等于操作符是不走索引。用其它相同功能的操作运算代替,如 a<>0 改为 a>0 or a<0 ;
like
a% 前缀可以走索引,其他情况建议使用全文检索引擎ES
SQL语句优化
在查询中不要使用 select *
考虑为经常查询的附属字段建立“覆盖索引”
sql加上nolock避免锁表
可利用索引的语句
以下假设在field1上有唯一索引I1,在field2上有非唯一索引I2。
--后者在索引扫描后要多一步ROWID表访问--
select field3,field4 from tb where field1='sdf' 快
select * from tb where field1='sdf' 慢
--前者可以迅速定位索引--
select field3,field4 from tb where field1>='sdf' 快
select field3,field4 from tb where field1>'sdf' 慢
函数不使用索引
select field3,field4 from tb where upper(field2)='RMN'
注意select into后的where子句
因为select into把数据插入到临时表,这个过程会锁定一些系统表,如果这个WHERE子句返回的数据过多或者速度太慢,会造成系统表长期锁定,诸塞其他进程。
避免使用临时表
(1)除非却有需要,否则应尽量避免使用临时表,相反,可以使用表变量代替;
(2)大多数时候,表变量驻扎在内存中,因此速度比临时表更快,临时表驻扎在TempDb数据库中,因此临时表上的操作需要跨数据库通信,速度自然慢。