SERVER中一些常见性能问题的总结

1.对查询进化,尽量避免全表描,首先   where     order   by   涉及的列上建立索引。  
   
  2.
尽量避免在   where   子句中字段   null   判断,否致引擎放弃使用索引而行全表描,如:  
  select   id   from   t   where   num   is   null  
 
可以在num置默认值0,确保表中num列没有null,然这样查询  
  select   id   from   t   where   num=0  
   
  3.
尽量避免在   where   子句中使用!=<>操作符,否将引擎放弃使用索引而行全表描。  
   
  4.
尽量避免在   where   子句中使用   or   接条件,否致引擎放弃使用索引而行全表描,如:  
  select   id   from   t   where   num=10   or   num=20  
 
可以这样查询  
  select   id   from   t   where   num=10  
  union   all  
  select   id   from   t   where   num=20  
   
  5.in  
  not   in   也要慎用,否致全表描,如:  
  select   id   from   t   where   num   in(1,2,3)  
 
连续的数,能用   between   就不要用   in   了:  
  select   id   from   t   where   num   between   1   and   3  
   
  6.
下面的查询也将致全表描:  
  select   id   from   t   where   name   like   '%abc%'  
 
若要提高效率,可以考全文索。  
   
   
7.如果在   where   子句中使用参数,也会致全表描。因SQL只有在运行才会解析局部量,但化程序不能将访问计划的选择到运行;它必编译时进选择。然而,如果在编译时建立访问计划,量的值还是未知的,因而无法作索引选择。如下面句将行全表描:  
  select   id   from   t   where   num=@num  
 
可以改为强查询使用索引:  
  select   id   from   t   with(index(
索引名))   where   num=@num  
   
  8.
尽量避免在   where   子句中字段行表达式操作,致引擎放弃使用索引而行全表描。如:  
  select   id   from   t   where   num/2=100  
 
:    
  select   id   from   t   where   num=100*2  
   
  9.
尽量避免在where子句中字段行函数操作,致引擎放弃使用索引而行全表描。如:  
  select   id   from   t   where   substring(name,1,3)='abc'--name
abcid  
  select   id   from   t   where   datediff(day,createdate,'2005-11-30')=0--‘2005-11-30’
生成的id  
 
:  
  select   id   from   t   where   name   like   'abc%'  
  select   id   from   t   where   createdate>='2005-11-30'   and   createdate<'2005-12-1'  
   
  10.
不要在   where   子句中的“=”边进行函数、算运算或其他表达式运算,否将可能无法正确使用索引。  
   
  11.
在使用索引字段作条件,如果索引是复合索引,那么必使用到索引中的第一个字段作条件才能保使用索引,否则该索引将不会被使用,并且尽可能的字段序与索引序相一致。  
   
 
12.不要写一些没有意查询,如需要生成一个空表构:  
  select   col1,col2   into   #t   from   t   where   1=0  
 
这类不会返回任何果集,但是会消耗系统资源的,改成这样  
  create   table   #t(...)  
   
  13.
很多候用   exists   代替   in   是一个好的选择  
  select   num   from   a   where   num   in(select   num   from   b)  
 
用下面的句替  
  select   num   from   a   where   exists(select   1   from   b   where   num=a.num)  
   
  14.
并不是所有索引对查询都有效,SQL是根据表中数据来查询优化的,当索引列有大量数据重复SQL查询可能不会去利用索引,如一表中有字段sexmalefemale几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。  
   
  15.
索引并不是越多越好,索引固然可以提高相   select   的效率,但同也降低了   insert     update   的效率,因   insert     update   有可能会重建索引,所以怎建索引需要慎重考具体情况而定。一个表的索引数最好不要超6个,若太多则应一些不常使用到的列上建的索引是否有 必要。  
   
  16.
尽可能的避免更新   clustered   索引数据列,因   clustered   索引数据列的序就是表记录的物理存储顺序,一旦致整个表记录序的整,会耗相当大的源。若用系需要繁更新   clustered   索引数据列,那么需要考是否索引建   clustered   索引。  
   
  17.
尽量使用数字型字段,若只含数信息的字段尽量不要设计为字符型,会降低查询接的性能,并会增加存是因引擎在查询会逐个比字符串中每一个字符,而于数字型而言只需要比一次就了。  
   
  18.
尽可能的使用   varchar/nvarchar   代替   char/nchar   ,因首先变长字段存小,可以省存,其次查询,在一个相对较小的字段内搜索效率然要高些。  
   
 
19.任何地方都不要使用   select   *   from   t   ,用具体的字段列表代替“*”,不要返回用不到的任何字段。  
   
 
20.尽量使用表量来代替临时表。如果表量包含大量数据,注意索引非常有限(只有主索引)。  
   
  21.
避免建和临时表,以减少系源的消耗。  
   
  22.
临时表并不是不可使用,适当地使用它可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集。但是,于一次性事件,最好使用出表。  
   
  23.
在新建临时,如果一次性插入数据量很大,那么可以使用   select   into   代替   create   table,避免造成大量   log   ,以提高速度;如果数据量不大,和系表的源,create   table,然后insert  
   
  24.
如果使用到了临时表,在存储过程的最后必将所有的临时除,先   truncate   table   ,然后   drop   table   这样可以避免系表的较长时间锁定。  
   
  25.
尽量避免使用游,因的效率差,如果游操作的数据超1万行,那么就应该改写。  
   
  26.
使用基于游的方法或临时表方法之前,找基于集的解决方案来解决问题,基于集的方法通常更有效。  
   
    27.
临时表一,游并不是不可使用。小型数据集使用   FAST_FORWARD   通常要于其他逐行理方法,尤其是在必引用几个表才能得所需的数据。在果集中包括的例程通常要比使用游标执行的速度快。如果开发时 ,基于游的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。  
   
 
28.在所有的存储过程和触器的开始处设   SET   NOCOUNT   ON   ,在时设   SET   NOCOUNT   OFF   。无需在行存储过程和触器的每个句后向客   DONE_IN_PROC   消息。  
   
  29.
尽量避免大事操作,提高系能力。  
   
 
30.尽量避免向客端返回大数据量,若数据量大,应该需求是否合理。  
   
 
具体的SQL句在很多情况下需要实际用情况来写,里不作叙述
posted @ 2009-09-05 17:42  yjhong  阅读(259)  评论(1编辑  收藏  举报