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

2015-01-22 22:48:51 · 作者: · 浏览: 31
=2
?
  BEGIN
?
  SET @参数=(SELECT 单位1参数 FROM 料件表 WHERE 料号 =@料号)
?
  UPDATE 入库表 SET 数量=数量*@参数,损坏数量=损坏数量*@参数,单位=1 WHERE CURRENT OF CUR
?
  END
?
  FETCH NEXT FROM CUR INTO @料号,@单位
?
  END
?
  CLOSE CUR
?
  DEALLOCATE CUR
?
  可以改写成:
?
  UPDATE A SET
?
  数量=CASE A.单位 WHEN 1 THEN A.数量*B. 单位1参数
?
  WHEN 2 THEN A.数量*B. 单位2参数
?
  ELSE A.数量 ?www.2cto.com ?
?
  END,
?
  损坏数量= CASE A.单位 WHEN 1 THEN A. 损坏数量*B. 单位1参数
?
  WHEN 2 THEN A. 损坏数量*B. 单位2参数
?
  ELSE A. 损坏数量
?
  END,
?
  单位=1
?
  FROM入库表 A, 料件表 B
?
  WHERE A.单位<>1 AND
?
  A.料号=B.料号
?
  C、 变量参与的UPDATE语句的例子
?
  SQL ERVER的语句比较灵活,变量参与的UPDATE语句可以实现一些游标一样的功能,比如:
?
  在
?
  SELECT A,B,C,CAST(NULL AS INT) AS 序号
?
  INTO #T
?
  FROM 表
?
  ORDER BY A ,NEWID()
?
  产生临时表后,已经按照A字段排序,但是在A相同的情况下是乱序的,这时如果需要更改序号字段为按照A字段分组的记录序号,就只有游标和变量参与的UPDATE语句可以实现了,这个变量参与的UPDATE语句如下:
?
  DECLARE @A INT
?
  DECLARE @序号 INT
?
  UPDATE #T SET
?
  @序号=CASE WHEN A=@A THEN @序号+1 ELSE 1 END,
?
  @A=A,
?
  序号=@序号
?
  D、如果必须使用游标,注意选择游标的类型,如果只是循环取数据,那就应该用只进游标(选项FAST_FORWARD),一般只需要静态游标(选项STATIC)。
?
  E、 注意动态游标的不确定性,动态游标查询的记录集数据如果被修改,会自动刷新游标,这样使得动态游标有了不确定性,因为在多用户环境下,如果其他进程或者本身更改了纪录,就可能刷新游标的记录集。 ?www.2cto.com ?
?
  7、 尽量使用索引
?
  建立索引后,并不是每个查询都会使用索引,在使用索引的情况下,索引的使用效率也会有很大的差别。只要我们在查询语句中没有强制指定索引,索引的选择和使用方法是SQLSERVER的优化器自动作的选择,而它选择的根据是查询语句的条件以及相关表的统计信息,这就要求我们在写SQL语句的时候尽量使得优化器可以使用索引。
?
  为了使得优化器能高效使用索引,写语句的时候应该注意:
?
  A、不要对索引字段进行运算,而要想办法做变换,比如
?
  SELECT ID FROM T WHERE NUM/2=100
?
  应改为:
?
  SELECT ID FROM T WHERE NUM=100*2
?
  SELECT ID FROM T WHERE NUM/2=NUM1
?
  如果NUM有索引应改为:
?
  SELECT ID FROM T WHERE NUM=NUM1*2
?
  如果NUM1有索引则不应该改。
?
  发现过这样的语句:
?
  SELECT 年,月,金额 FROM 结余表
?
  WHERE 100*年+月=2007*100+10
?
  应该改为:
?
  SELECT 年,月,金额 FROM 结余表
?
  WHERE 年=2007 AND
?
  月=10
?
  B、 不要对索引字段进行格式转换
?
  日期字段的例子:
?
  WHERE CONVERT(VARCHAR(10), 日期字段,120)=’2008-08-15’
?
  应该改为
?
  WHERE日期字段〉=’2008-08-15’ AND 日期字段<’2008-08-16’
?
  ISNULL转换的例子:
?
  WHERE ISNULL(字段,’’)<>’’应改为:WHERE字段<>’’
?
  WHERE ISNULL(字段,’’)=’’不应修改
?
  WHERE ISNULL(字段,’F’) =’T’应改为: WHERE字段=’T’
?
  WHERE ISNULL(字段,’F’)<>’T’不应修改
?
  C、 不要对索引字段使用函数
?
  WHERE LEFT(NAME, 3)='ABC' 或者WHERE SUBSTRING(NAME,1, 3)='ABC'
?
  应改为: ?www.2cto.com ?
?
  WHERE NAME LIKE 'ABC%'
?
  日期查询的例子:
?
  WHERE DATEDIFF(DAY, 日期,'2005-11-30')=0应改为:WHERE 日期 >='2005-11-30' AND 日期 <'2005-12-1‘
?
  WHERE DATEDIFF(DAY, 日期,'2005-11-30')>0应改为:WHERE 日期 <'2005-11-30‘
?
  WHERE DATEDIFF(DAY, 日期,'2005-11-30')>=0应改为:WHERE 日期 <'2005-12-01‘
?
  WHERE DATEDIFF(DAY, 日期,'2005-11-30')<0应改为:WHERE 日期>='2005-12-01‘
?
  WHERE DATEDIFF(DAY, 日期,'2005-11-30')<=0应改为:WHERE 日期>='2005-11-30‘
?
  D、不要对索引字段进行多字段连接
?
  比如:
?
  WHERE FAME+ ’.’+LNAME=‘HAIWEI.YANG’
?
  应改为:
?
  WHERE FNAME=‘HAIWEI’ AND LNAME=‘YANG’
?
  8、 注意连接条件的写法
?
  多表连接的连接条件对索引的选择有着重要的意义,所以我们在写连接条件条件的时候需要特别的注意。
?
  A、多表连接的时候,连接条件必须写全,宁可重复,不要缺漏。
?
  B、 连接条件尽量使用聚集索引
?
  C、 注意ON部分条件和WHERE部分条件的区别
?
  9、 其他需要注意的地方
?
  经验表明,问题发现的越早解决的成本越低,很多性能问题可以在编码阶段就发现,为了提早发现性能问题,需要注意:
?
  A、程序员注意、关心各表的数据量。
?
  B、 编码过程和单元测试过程尽量用数据量较大的 数据库测试,最好能用实际数据测试。
?
  C、 每个SQL语句尽量简单 ?www.2cto.com ?
?
  D、不要频繁更新有触发器的表的数据
?
  E、 注意数据库函数的限制以及其性能
?
  10、 学会分辩SQL语句的优劣
?
  自己分辨SQL语句的优劣非常重要,只有自己能分辨优