日期:2014-05-18  浏览次数:20558 次

【SQL Server 优化性能的几个方面】
排版不好,详见博文地址:http://blog.csdn.net/feixianxxx/archive/2010/04/24/5524819.aspx

(一).数据库的设计

 
SQL code
可以参看最近论坛上出现一个精华帖http://topic.csdn.net/u/20100415/10/a377d835-acbd-4815-8bcb-b367f88ac8b5.html?92227
   数据库设计包含物理设计和逻辑设计:
   物理设计上可以通过使用RAID硬件架构。
   简单说下使用策略:
a.RAID0可以用在只读的数据库数据表,或者是经过复制过来的数据库上,如果你对数据丢失不敏感的话也可以使用,总之这个level下是高性能无冗余;
b.RAID 5 与RAID1 不同之处就是多了奇偶校验,所有的奇偶校验的信息会遍布各个磁盘,性能上要比RAID1高些,但是一旦发生磁盘I/O失败,就会造成性能急剧下降,同时这种方法也在RAID0 与RAID1间折了中,是比较通用的做法。
c.RAID 10 就是RAID0 与 RAID1的组合,它提供了高性能,高可用性,性能上要比RAID5好,特别适合大量写入的应用程序,但是就是成本比较高无论是多少块磁盘你都是将损失一半的磁盘存储

  逻辑设计上可以通过使用数据库的一些组件比如表、约束等,在这里首先提下文件组的使用。当你经费不足,无法购买一个完整的RAID系统的时候,你可以考虑文件组。
  文件和文件组体系结构一些小节:http://blog.csdn.net/feixianxxx/archive/2010/01/28/5267290.aspx
  它的原理就是多硬盘同时读取,减少磁盘空间争夺,提高读取效率。

我在这再稍微说几点:

a.范式和数据表的分割和合并
  我们在设计数据库的时候一般会追求规范,一般会至少达到3NF.在这之后,也许会因为表中某些经常用于存储查询的字段而把它们从表中分割,否则大量用户
  同时大量访问一个热门表,效率会变差。当然有时候也会进行合并表的设计,这样可以用少量的冗余换来减少过多连接的运算。
  具体关于这个设计表到什么程度,是否需要分割和合并都是因业务需求和系统承载力而定的,可以参看更多这方面的书籍。

b.主键与外键
  作为表与表之间的联系,最直接的就是通过主外键进行联系。主键对于一个表来说是非常重要的,它能在表中作为行的唯一标识存在,要求:唯一性,不可为NULL和最小性。
  其中最小性指的是作为主键一定要窄。如果键值过大,由于经常存取,它会让数据库系统变得没有效率,而且它需要维护。一般使用1-4字节的字段作为主键。

c.表字段的取舍
  尽量让你的表字段类型“适可而止”,即在符合一般需求长度的前提下,最多稍微增加长度,不要过多浪费。字段存储直接体现在页中。行长越短,一页就可以存储越多的记录行。
  当我们从硬盘中取数据的时候以页为单位,一页中包含的记录越多,代表放入缓存区的记录就越多,吞吐量就越大。
  1.如果字段的内容比较固定 比如性别 身份证号码 手机号码等 就是用定长的 char 或者nchar
  2.如果字段的内容变化幅度比较大 则介意使用 varchar或者nvarchar
  3.一般不要让字段可以为NULL,这样会带来一些处理上不必要的消耗,可以使用默认值代替它
  4.尽可能的使用约束来维护数据完整性,不要过分依赖触发器或者存储过程来维护。
  
d.日常维护计划安排
  数据维护计划,比如备份,重建索引,复制数据等批处理消耗资源的操作尽量在系统空闲的时候进行。

e.前端程序对基础表的存取
  尽量让程序通过据库中的存储过程,视图,函数来存取数据,不要让其直接在基础表上进行操作。





(二).数据库查询的优化(T-SQL优化)
  这个内容太大了,就挑着点来说
SQL code
  
1.尽量多的使用查询参数(SARG)
  它的一般格式:字段 部分的运算符 《常数或者变量》
  这里的部分运算符包括:= > < >= <= BETWEEN AND 还有LIKE 后面不是以%开头的。
  非SARG的语法,索引一般不起作用。下面列举一些违反SARG语法的做法:

  a.对数据字段进行了运算
    我直接举例子(测试过的): where col_1+col_2='ab' 是不可以用到索引的 ;
                   where col1='a' adn col_2='b'则可以用到字段上的索引;
                   where col_3+1=4 不可以用到;where col_3=4-1 可以用到
  b.不要对字段使用逆运算符
    不要对字段使用某些逆运算符,比如   not in not like  (2000的书上说<> != !>等也是会屏蔽索引的 我在08上是可以使用索引的 欢迎有2000环境的朋友测试)
     例子(测试过的):where id not like '1%' 或者where id not in(1,2,3) 都是不能用到索引的
  
 c.不要对字段使用函数
   使用比如 substring left datediff 等等函数 但是你可以巧妙的用SARG方式来替代某些函数的功能
   比如 left(col,2)='av' 可以用 col like 'av%' 或者 abs(col-1)>100 可以用 col>101 or col<-99

 d.不要使用OR运算符
   使用了OR运算符,多个条件中的字段只要有一个没有合适的索引,其他字段的索引都失去索引效果,都将整表扫描。(注意索引扫描和表扫描效率差不多)
 
 但是注意在where中使用非SARG也不一定就用不到索引。有时候包含非SARG的条件 但是还是会对SARG部分进行索引利用的。

2.大量数据插入
 
 a.在进行大容量数据插入的时候,可以通过BCP BULK INSERT选项尽量屏蔽表上的触发器、约束,甚至删除表上索引,这样可以让插入操作快很多。
   如果你担心数据的不规则,可以先将数据导入到一个临时表,然后再数据库里面过滤掉不规则数据后,再次由临时表插入目标表。
 b.同样的大容量插入,推荐使用BULK INSERT。因为通常情况下,它比BCP要快。
 c.使用BCP 或者 BULK INSERT插入时候,采用表锁定而不是默认的记录锁。
 d.如服务器多核,可以尽量让多客户端并行对表插入。
 e.如果插入的数据需要转换,不要使用DTS等工具直接对记录的转化,可以使用先插入临时表,在临时表内转化后进行第二次导入。
 



(三)索引的合理设计
 
SQL code
这又是很大的一块内容,也不是三言两语能说完的,介于内容的量和本人水平以及实践太少,就不写了。
     我提供几篇关于索引的文章: 
     http://www.cnblogs.com/bhtfg538/(里面有几篇)
     http://hi.baidu.com/dusongw/blog/item/4090493d6ec0cdee3d6d97a6.html




(四)前端应用程序设计
 
SQL code
应用程序作为数据的控制使用端,它将决定何时使用数据,如何使用数据,得来的数据结果又如何处理。它将直接影响服务器端的活动,对整个性能非常关键。
      下面说几点应用程序设计的注意点:
1.减少网络流量
   你可以通过使用存储过程,甚至可以使用 SET NOCOUNT 设置来禁用一些影响行数。还有就是要尽可能少的返回数据量,什么意思呢?就是说,如果你的程序只需要表
   中的某些数据,你就不要返回整个表的数据,然后再筛选,直接通过条件在服务器筛选好后再传过来。
2.限