Sql Server性能优化浅谈

数据库性能问题对编写Sql脚本的人员来说,是一个不得不考虑的问题.做为一名开有时也需要这方面的知识.我总结了一些关于优化的基本知识,供大家参考.

 

一. 数据库设计与性能
 好的数据库设计可以提高数据库的性能.在设计数据库时考虑以下原则可以提高性能.
 a. 使用非规范化数据库
  1)规范化的数据库可防止数据存在功能相关性,以便轻松、高效地更新数据库。但是,查询数据库时可能需要联接许多表来组合信息。随着联接表数目的增多,查询运行时间会大大增加。因此,规范化的数据库并不一定是最佳的选择。通常,如果有相当多的查询需要联接五个或六个以上的表,则应考虑使用非规范化数据库。
  2)此外对一些使用统计函数计算后的值,计算后存储起来,可以节省大量查询时间,但是使用此方法时需要在表中多维护一列。
 b. 采用可变长度列还是固定长度列
  与固定长度列相比,可变长度列的缺点是一些操作的效率不高。例如,如果可变长度列开始时很小,而某 UPDATE 子句使其显著增大,则可能就要重新定位记录。此外,频繁的更新会导致数据页随着时间推移变得比较零碎。因此,在数据长度变化不大并且需要频繁进行更新时,建议使用固定长度列。
 c. 创建长度较小的行
  页中可容纳的行数取决于各行的紧凑程度。如果行较小,则页中可以容纳更多的行。因此,对行较为紧凑的表执行的单磁盘操作可以检索更多的行,从而使操作更为有效。此外,存储引擎缓存中也可以包含更多的行,而这可能会提高命中率。使用紧凑的行还可以防止浪费数据页上的空间。使用较大的行时,通常就会有这种浪费情况。
  1)使操作更为有效
  2)提高命中率
  假设您有一个表,其中某些列具有非常稳定的值,而其他列的值更改非常频繁。那么,将这个表拆分为两个表(一个表包含频繁引用的列,另一个表包含稳定的列)是很有意义的。通过创建两个表,即可拥有长度较小的行的所有优点。但缺点是需要使用联接来组合信息。
 d. 使用长度较小的键
  具有一个或少数几个键列的索引称为窄索引。具有许多键列的索引称为宽索引。宽索引的键长度通常较大。一个极端的索引示例是包括表中的所有列。通过创建这样的索引,可以有效地制作原始表的副本。不过,在数据库大小和查询性能方面,这种做法的效率都十分低下。
  1)较小的索引键占用的空间更小,并且更为有效。
  2)使用长度变化不大,紧凑的主键十分有用.


二. 查询与性能 
1. 索引
  a. 创建高选择性索引
  选择性是指符合条件的行数与总行数之比。如果比率较低,索引就是高选择性的。唯一索引具有最高的选择性。sp_show_statistics 存储过程,您可以评估索引的选择性.
 b. 创建多列索引
  在创建多列查询时,应该将选择性最高的列放在键中的最左端。
 c. 避免对小表创建索引
  因为进行表扫描通常效率更高,所以要避免对非常小的表创建索引。这会节省加载和处理索引页的开销。
 d. 与筛选子句一起使用索引
  索引可以用于提高某些类型的筛选子句的计算速度。虽然所有筛选子句都会减小查询的最终结果集,但是某些筛选子句还可以帮助减小所需扫描的数据量。筛选需要使用到SARG运算符(搜索参数).
  SARG 运算符包括 =、>、<、>=、<=、IN、BETWEEN,有时还包括 LIKE
  非SARG 运算符包括 NOT、<>、NOT EXISTS、NOT IN、NOT LIKE 和内部函数
  当子查询使用到SARG 运算符时可以减少所需扫描的数据量,因为非SARG运算符需全表扫描,不能使用索引.
 e. 对 ORDER-BY/GROUP-BY/DISTINCT 列创建索引以缩短响应时间
  RDER- BY、GROUP-BY 和 DISTINCT 操作都是排序类型的操作。SQL Server Compact Edition 查询处理器使用两种方法进行排序。如果记录已经按索引进行排序,则处理器只使用索引。否则,处理器必须先使用临时工作表对记录进行排序。
  在使用多列索引的情况下,为了使 ORDER-BY 或 GROUP-BY 处理特定索引,ORDER-BY 或 GROUP-BY 列必须与预先指定的一组索引列匹配,而且顺序要完全相同。例如,索引 CREATE INDEX Emp_Name ON Employees ("Last Name" ASC, "First Name" ASC) 有助于优化下列查询:
  • ... ORDER BY / GROUP BY "Last Name" ...
  • ... ORDER BY / GROUP BY "Last Name", "First Name" ...
  为了使 DISTINCT 操作处理多列索引,映射列表必须与所有索引列匹配,尽管顺序不必完全相同。上面的索引有助于优化下列查询:
  • ... DISTINCT "Last Name", "First Name" ...
  • ... DISTINCT "First Name", "Last Name" ...
  但对下列查询,它并没有帮助:
  • ... DISTINCT "First Name" ...
  • ... DISTINCT "Last Name" ...
  如果您的查询始终返回唯一行,请不要指定 DISTINCT 关键字,因为它只会增加开销。
 
 f. 不能使用索引的操作
  1). 不使用IS NULL 或IS NOT NULL操作(判断字段是否为空),索引中不能包括NULL,所以这样的查询无法使用索引.使用>或<替换.
  2)采用函数处理的字段不能利用索引
  3)进行了显式或隐式的运算的字段不能进行索引(select * from t where (t.a + t.b) = 'abc')(select * from t where t.a = 'abc')
  4)条件内包括了多个本表的字段运算时不能进行索引(select * from t where t.a = t.b).

 

三. 子查询与性能
 重写IN子查询,使用EXISTS或JOIN可以有效增加查询效率.

 

四. 关键字性能的差别
 a. union 与 union all
  UNION在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果。而UNION ALL只是简单的将两个结果合并后就返回。这样,如果返回的两个结果集中有重复的数据,那么返回的结果集就会包含重复的数据了。从效率上说,UNION ALL 要比UNION快很多. 


 
五. 连接与优化
 a. 优化带宽
 b. 同步超时属性
 c. 超时优化

你可能感兴趣的:(Sql,Server)