SQL Server优化的方法<三>(五)

2015-01-22 22:48:51 · 作者: · 浏览: 33
劣才能写出高效的语句。
?
  A、 查看SQL语句的执行计划,可以在查询分析其使用CTRL+L图形化的显示执行计划,一般应该注意百分比最大的几个图形的属性,把鼠标移动到其上面会显示这个图形的属性,需要注意预计成本的数据,也要注意其标题,一般都是CLUSTERED INDEX SEEK 、INDEX SEEK 、CLUSTERED INDEX SCAN 、INDEX SCAN 、TABLE SCAN等,其中出现SCAN说明语句有优化的余地。也可以用语句
?
  SET SHO WPLAN_ALL ON
?
  要执行的语句
?
  SET SHOWPLAN_ALL OFF
?
  查看执行计划的文本详细信息。
?
  B、 用事件探查器跟踪 系统的运行,可疑跟踪到执行的语句,以及所用的时间,CPU用量以及I/O数据,从而分析语句的效率。
?
  C、 可以用WINDOWS的系统性能检测器,关注CPU、I/O参数
?
  四、 测试、试运行、维护阶段
?
  测试的主要任务是发现并修改系统的问题,其中性能问题也是一个重要的方面。重点应该放在发现有性能问题的地方,并进行必要的优化。主要进行语句优化、索引优化等。
?
  试运行和维护阶段是在实际的环境下运行系统,发现的问题范围更广,可能涉及操作系统、网络以及多用户并发环境出现的问题,其优化也扩展到操作系统、网络以及数据库物理存储的优化。
?
  这个阶段的优花方法在这里不再展开,只说明下索引维护的方法:
?
  A、 可以用DBCC DBREINDEX语句或者SQL SERVER维护计划设定定时进行索引重建,索引重建的目的是提高索引的效能。
?
  B、 可以用语句UPDATE STATISTICS或者SQL SERVER维护计划设定定时进行索引统计信息的更新,其目的是使得统计信息更能反映实际情况,从而使得优化器选择更合适的索引。
?
  C、 可以用DBCC CHECKDB或者DBCC CHECKTABLE语句检查数据库表和索引是否有问题,这两个语句也能修复一般的问题。
?
  D、
?
  五、 网上资料中一些说法的个人不同意见
?
  1、 “应尽量避免在 WHERE 子句中对字段进行 NULL 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
?
  SELECT ID FROM T WHERE NUM IS NULL
?
  可以在NUM上设置默认值0,确保表中NUM列没有NULL值,然后这样查询:
?
  SELECT ID FROM T WHERE NUM=0” ?www.2cto.com ?
?
  个人意见:经过测试,IS NULL也是可以用INDEX SEEK查找的,0和NULL是不同概念的,以上说法的两个查询的意义和记录数是不同的。
?
  2、 “应尽量避免在 WHERE 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。”
?
  个人意见:经过测试,<>也是可以用INDEX SEEK查找的。
?
  3、 “应尽量避免在 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”
?
  个人意见:主要对全表扫描的说法不赞同。
?
  4、 “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”
?
  个人意见:主要对全表扫描的说法不赞同。
?
  5、 “如果在 WHERE 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:
?
  SELECT ID FROM T WHERE NUM=@NUM
?
  可以改为强制查询使用索引:
?
  SELECT ID FROM T WITH(INDEX(索引名)) WHERE NUM=@NUM”
? www.2cto.com ?
  个人意见:关于局部变量的解释比较奇怪,使用参数如果会影响性能,那存储过程就该校除了,我坚持我上面对于强制索引的看法。
?
  6、 “尽可能的使用 VARCHAR/NVARCHAR 代替 CHAR/NCHAR ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。”
?
  个人意见:“在一个相对较小的字段内搜索效率显然要高些”显然是对的,但是字段的长短似乎不是由变不变长决定,而是业务本身决定。在SQLSERVER6.5或者之前版本,不定长字符串字段的比较速度比定长的字符串字段的比较速度慢很多,所以对于那些版本,我们都是推荐使用定长字段存储一些关键字段。而在2000版本,修改了不定长字符串字段的比较方法,与定长字段的比较速度差别不大了,这样为了方便,我们大量使用不定长字段。
?
  7、 关于连接表的顺序或者条件的顺序的说法,经过测试,在SQL SERVER,这些顺序都是不影响性能的,这些说法可能是对ORACLE有效。

?
?
作者 Tellme_C#