- 查询优化建议
- 在查询中不要出现select *,原因可能会产生额外的书签查找 另外一个原因减少网络传输
- 查询最好使用窄宽度列做为条件 相对于 int 和varchar 类型 首选int
- 插入大量的数据时候避免用循环插入,即使使用循环也要放入到一个事务中去
- where 条件后避免使用函数,或者数据类型转换可能会导致索引失效
- 不要使用旧的链接 如sql-89语法: from table1,table2 这样可能产生笛卡尔集,查询分析器无法使用loop join,hash join,merge join ,解决方式 使用inner join 内链接
- where 及order by 上建立索引
- 减少对null的查询,null会导放弃索引 使用表扫描 所以设计表的时候 字段设置默认值 int 为0 varchar 为''
- 应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描 可以使用 NOT EXISTS 如果查询字段连续的话可以使用 between and 来代替
- 应尽量避免在 WHERE 子句中使用 OR 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描 可以使用union all 代替
- in 和not in 也要慎用 但是有些帖子说 in(数字) 要比 in (子查询) 要好 使用 exists 代替in
但是据说 in 里边如果是具体值的话可能会效率高点 比如in(1,3,4)
- 避免使用like %%也会导致索引失效 可以使用全文索引代替
- 如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:select id from t where num=@num 可以改为强制查询使用索引:select id from t with(index(索引名)) where num=@num
- 尽可能不使用游标 因为游标相当每次循环都 select 如果使用游标那么 游标要设置只读
- 在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON ,在结束时设置 SET NOCOUNT OFF 。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息。
- 尽量避免大事务操作,提高系统并发能力。如果有这种需求
- 能使用distict就不要用group by
- 注意UNION和UNION ALL 的区别。UNION ALL好
- 在查询Select语句中用Where字句限制返回的行数,避免表扫描,如果返回不必要的数据,浪费了服务器的I/O资源,加重了网络的负担降低性能。如果表很大,在表扫描的期间将表锁住,禁止其他的联接访问表,后果严重。
- 减少 I/O 尽可能的使用 index seek(索引查找 ) 不使用indexScan( 索引扫描 )
- 尽可能不使用触发器 使用存储过程代替触发器 因为触发器没有编译到执行计划中。
- 减少数据库访问量能缓存数据的缓存数据。
- 合理使用视图 使用视图索引 视图避免查询语句的嵌套
- 避免长事务因为长时间锁表会影响查询 分解事务 把事务颗粒化
这个是我对sqlserver 语句优化的一些总结 如果大家有好的建议不防再补充上。众人拾柴火焰高,共同进步。