zzbdqn5888 2010-01-18 22:21
浏览 211
已采纳

怎么优化sql语句呀?

:D 如题。。。

  • 写回答

4条回答 默认 最新

  • hongmiao88 2010-01-18 22:23
    关注

    1、查询时不返回不需要的行、列
    业务代码要根据实际情况尽量减少对表的访问行数,最小化结果集,在查询时,不要过多地使用通配符如:select * from table1语句,要用到几列就选择几列,如:select col1,col2 from table1;在可能的情况下尽量限制结果集行数如:select top 100 col1,col2,col3 from talbe2,因为某些情况下用户是不需要那么多的数据的。

    2、合理使用EXISTS, NOT EXISTS字句
    如下所示:

     SELECT SUM(T1.C1) FROM T1 WHERE ((SELECT COUNT(*) FROM T2 WHERE T2.C2=T1.C2)>0)
    
     SELECT SUM(T1.C1) FROM T1 WHERE EXISTS(SELECT * FROM T2 WHERE T2.C2=T1.C2)
    
    
    
     两种产生相同的结果,但是后者的效率显然要高过于前者。银行后者不会产生大量锁定的表扫描或是索引扫描。
    
    
    
     经常需要些一个T_SQLL语句比较一个父结果集和子结果集,从而找到是否存在在父结果集中有而在子结果集中乜嘢的记录,如:
    
     SELECT _a.hdr_key FROM hdr_tb1 a               -----------tb1 a 表示tb1用别名a代替
    
     WHERE NOT EXISTS (SELECT * FROM dt1_tb1 b WHERE a.hdr_key = b.hdr_key)
    
    
    
     SELECT _a.hdr_key FROM hdr_tb1 a               -----------tb1 a 表示tb1用别名a代替
    
     LEFT JION dt1_tb1 b ON  a.hdr_key = b.hdr_key WHERE b.hdr_key IS NULL
    
    
    
     SELECT hdr_key  FROM hdr_tb1
    
     WHERE hdr_key NOT IN (SELECT hdr_key FROM dt1_tb1)
    
    
    
     三种写法都可以得到同样的结果集,但是效率是依次降低
    

    3、充分利用连接条件
    在某种情况下,两个表之间可能不止一个的连接条件,这时在where 字句中将谅解条件完整的写上,有可能大大提高查询速度。

     例:
    
    a)、SELECT SUM(A.AMOUNT) FROM ACCOUNT A left jion CARD B on A.CARD_NO = B.CARD_NO
    
    
    
    b)、SELECT SUM(A.AMOUNT) FROM ACCOUNT A left jion CARD B on A.CARD_NO = B.CARD_NO AND A.ACCOUNT_NO = B.ACCOUNT_NO
    
     第二句将比第一句执行快得多。
    

    4、WHERE 字句中关系运算符的选择
    a)、在关系运算中,尽量使用=,尽量不要使用<>。

      b)、WHERE字句中尽量不要使用NOT运算符,如:NOT IN ,NOT EXISTS, NOT>、NOT<等等NOT运算符一般可以去除。如NOT SALARY >10000K可以改为:salary<=100,如避免使用NOT IN,可以使用 left outer jion代替它。
    
      c)、where 字句中条件表达式间逻辑关系为AND时,将条件为假的概率高的放在前面,概率相同、条件计算简单的放在前面。
    
      d)、尽可能不要用Order by字句。使用Order by时,尽量减少列数、尽量减少排序数据行数、排序字段尽量是数字型(尽量不要是字符型)。GROUP BY、 SELECT DITINCT、UNION等字句,也经常导致Order运算。
    
      e)、不要使用Select count(*)方式来判断记录是否存在,建议使用Select top 1 from table1 where ……。
    
      f)、不要使用Group by而没有聚合列。
    
     g)、避免Select 语句的Where 字句条件用于假。如:where 1=0;
    
    h)、如果有多表连接时,应该有主从表之分,并尽量从一个表读取数,如select a.col1,a.col2 from a jion b on a.col3=b.col4 where b.col5=’a’.
    
     i)、在where 字句中,如果有多个过滤条件,应将所有列或过滤记录数量最多的条件应该放在前面。
    

    二、使用Truncate清空表

      Truncate会将表中记录全部清空,而不能有选择性的删除指定记录。而DELETE可以指定删除的记录。由于Truncate操作在TransactionLog中只记录被Truncate的页号,而DELETE需要记载被删除记录的详细内容,因此Truncate会比DELETE更迅速。对大数据表使用Truncate,效果更加明显。Truncate Table只会删除表中记录。而不会对表的索引和结构造成影响。
    

    三、Union和Union all

      Union将两个结果集合并后,会消除重复记录,而Union all不会消除重复记录,而是直接将两个结果集直接合并。明确得知两个结果集中没有重复记录或者重复记录不影响使用,建议使用Union all 代替Union。因为Union在消除重复记录的过程中需要进行排序过滤操作,对大结果集这种排序操作会非常影响性能。下面是Union 和Union all的简单性能比较:
    

    ---------------Union

    select * from table1 where code=’01’

    Union

    select * from table1 where code=’02’

    ---------------Union all

    select * from table1 where code=’01’

    union all

    select * from talbe1 where code=’02’

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突
  • ¥15 超声波模块测距控制点灯,灯的闪烁很不稳定,经过调试发现测的距离偏大
  • ¥15 import arcpy出现importing _arcgisscripting 找不到相关程序