SQL基础系列(4)-性能优化建议

 

10.1 连接查询表的顺序问题

SQLSERVER的解析器按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表driving table)将被最先处理,在FROM子句中包含多个表的情况下,必须选择记录条数最少的表作为基础表,当SQLSERVER处理多个表时,会运用排序及合并的方式连接它们。首先,扫描第一个表(FROM子句中最后的那个表)并对记录进行排序;然后扫描第二个表(FROM子句中最后第二个表);最后将所有从第二个表中检索出的记录与第一个表中合适记录进行合并

 

如果有3个以上的表连接查询,那就需要选择交叉表(intersection table)作为基础表,交叉表是指那个被其他表所引用的表

 

10.2 Where条件的顺序问题

SQLSERVER采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前,那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾  

 

10.3 SELECT子句中避免使用’*’。

在SELECT子句中列出所有的COLUMN时,使用动态SQL列引用’*’是一个方便的方法,不幸的是,这是一个非常低效的方法。实际上,SQLSERVER在解析的过程中,会将’*’依次转换成所有的列名,这个工作是通过查询数据字典完成的,这意味着将耗费更多的时间    

 

10.4 减少查询次数

10.5 用Where子句替换HAVING子句 

10.6减少对表的查询

10.7用EXISTS替代IN

在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接,在这种情况下,使用EXISTS(或NOT EXISTS)通常将提高查询的效率 

 

低效 

   SELECT * 

   FROM dbo.Orders

   WHERE Id_P>0 AND Id_P  IN (SELECT id 

   FROM dbo.Persons 

   ) 

 

    

高效 

   SELECT * 

   FROM Orders 

   WHERE Id_P >0 AND  EXISTS (SELECT id 

   FROM Persons   WHERE Persons.id = Orders.Id_P 

  ) 

10.8用NOT EXISTS替代NOT IN  

 

在子查询中,NOT IN子句将执行一个内部的排序和合并,无论在哪种情况下,NOT IN都是最低效的,因为它对子查询中的表执行了一个全表遍历 ,为了避免使用NOT IN,可以把它改写成外连接(Outer Joins)或NOT EXISTS

低效 

   SELECT * 

   FROM dbo.Orders

   WHERE Id_P>0 AND Id_P not IN (SELECT id 

   FROM dbo.Persons 

   ) 

 

    

高效 

   SELECT * 

   FROM Orders 

   WHERE Id_P >0 AND not EXISTS (SELECT id 

   FROM Persons   WHERE Persons.id = Orders.Id_P 

  ) 

10.9用表连接替换EXISTS  

 

10.10用EXISTS替换DISTINCT 

低效 

 

  SELECT DISTINCT Id_P

   FROM Orders , Persons 

   WHERE Orders.Id_P = Persons.id 

    

   高效 

  SELECT Id_P

   FROM Orders

   WHERE EXISTS (SELECT id

   FROM Persons

   WHERE Persons.id = Orders.Id_P); 

 

10.11用索引提高效率  

不要在索引上使用模糊查询

不要在索引列上进行计算

索引列不要加is null或is not null

 

10.12使用union allunion

 

本文内容为学习

http://www.cnblogs.com/zhougb/archive/2009/05/05/1449708.html而来

若涉嫌侵犯您的权益,请及时联系本人

posted @ 2016-06-09 15:39  逆风飞行  阅读(202)  评论(0编辑  收藏  举报