1.应尽量避免在  where  子句中对字段进行   null  值推断,否则将导致引擎放弃使用索引而进 

行全表扫描,如:    

select id from t where num is null    





能够在num 上设置默认值0 ,确保表中num 列没有null 值,然后这样查询:    

select id from t where num=0  







2.应尽量避免在  where  子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫 

描。优化器将无法通过索引来确定将要命中的行数, 因此须要搜索该表的全部行。  





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  也要慎用,由于IN 会使系统无法使用索引,而仅仅能直接搜索表中的数据。如:    

select id from t where num in(1,2,3)    



对于连续的数值。能用   between  就不要用  in  了:    

select id from t where num between 1 and 3  





5.尽量避免在索引过的字符数据中,使用非打头字母搜索。

这也使得引擎无法利用索引。

见例如以下样例:    

SELECT * FROM T1 WHERE NAME LIKE ‘%L%’    

SELECT * FROM T1 WHERE SUBSTING(NAME,2,1)=’L’    

SELECT * FROM T1 WHERE NAME LIKE ‘L%’    

即使 NAME  字段建有索引。前两个查询依旧无法利用索引完毕加快操作,引擎不得不正确全 

表全部数据逐条操作来完毕任务。而第三个查询可以使用索引来加快操作。

6.必要时强制查询优化器使用某个索引。如在  where  子句中使用參数,也会导致全表扫描。 

由于 SQL       仅仅有在执行时才会解析局部变量,但优化程序不能将訪问计划的选择推迟到执行 

时;它必须在编译时进行选择。然  而。假设在编译时建立訪问计划,变量的值还是未知的。 

因而无法作为索引选择的输入项。如以下语句将进行全表扫描:    

select id from t where num=@num    

能够改为强制查询使用索引:    

select id from t with(index(索引名)) where num=@num  



7.应尽量避免在  where  子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行 

全表扫描。如:    

SELECT * FROM T1 WHERE F1/2=100    

应改为:    

SELECT * FROM T1 WHERE F1=100*2    

SELECT * FROM RECORD WHERE SUBSTRING(CARD_NO,1,4)=’5378’    

应改为:    

SELECT * FROM RECORD WHERE CARD_NO LIKE ‘5378%’    

SELECT member_number, first_name, last_name FROM members    

WHERE DATEDIFF(yy,datofbirth,GETDATE()) > 21    



应改为:    

SELECT member_number, first_name, last_name FROM members    

WHERE dateofbirth < DATEADD(yy,-21,GETDATE())    

即:不论什么对列的操作都将导致表扫描,它包含数据库函数、计算表达式等等,查询时要尽可 

能将操作移至等号右边。

8.应尽量避免在where 子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表 

扫描。如:    

select id from t where substring(name,1,3)='abc'--name 以abc 开头的id    

select id from t where datediff(day,createdate,'2005-11-30')=0--           ‘2005-11-30 ’生成的id    

应改为:    

select id from t where name like 'abc%'    

select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'  



9.不要在  where  子句中的“= ”左边进行函数、算术运算或其它表达式运算,否则系统将可 

能无法正确使用索引。  



10.在使用索引字段作为条件时。假设该索引是复合索引。那么必须使用到该索引中的第一 

个字段作为条件时才干保证系统使用该索引,否则该索引将不会被使用。而且应尽可能的让 

字段顺序与索引顺序相一致。  





11.非常多时候用  exists 是一个好的选择:    

select num from a where num in(select num from b)    

用以下的语句替换:    

select num from a where exists(select 1 from b where num=a.num)    

SELECT SUM(T1.C1)FROM T1 WHERE(    

(SELECT COUNT(*)FROM T2 WHERE T2.C2=T1.C2>0)    

SELECT SUM(T1.C1) FROM T1WHERE EXISTS(    

SELECT * FROM T2 WHERE T2.C2=T1.C2)    

两者产生同样的结果,可是后者的效率显然要高于前者。由于后者不会产生大量锁定的表扫 

描或是索引扫描。

假设你想校验表里是否存在某条纪录,不要用count(*)那样效率非常低。并且浪费server资源。

能够用EXISTS 取代。如:    

IF (SELECT COUNT(*) FROM table_name WHERE column_name = 'xxx')    

能够写成:    

IF EXISTS (SELECT * FROM table_name WHERE column_name = 'xxx')    

常常须要写一个T_SQL 语句比較一个父结果集和子结果集。从而找到是否存在在父结果集中 

有而在子结果集中没有的记录,如:    

SELECT a.hdr_key FROM hdr_tbl a---- tbl a  表示tbl 用别名a 取代    

WHERE NOT EXISTS (SELECT * FROM dtl_tbl b WHERE a.hdr_key = b.hdr_key)    

SELECT a.hdr_key FROM hdr_tbl a    

LEFT JOIN dtl_tbl b ON a.hdr_key = b.hdr_key WHERE b.hdr_key IS NULL    

SELECT hdr_key FROM hdr_tbl    

WHERE hdr_key NOT IN (SELECT hdr_key FROM dtl_tbl)    

三种写法都能够得到相同正确的结果,可是效率依次减少。  





12.尽量使用表变量来取代暂时表。假设表变量包括大量数据,请注意索引很有限(仅仅有 

主键索引)。  





13.避免频繁创建和删除暂时表。以降低系统表资源的消耗。

14.暂时表并非不可使用。适当地使用它们能够使某些例程更有效,比如。当须要反复引 

用大型表或经常使用表中的某个数据集时。可是。对于一次性事件,最好使用导出表。  



15.在新建暂时表时。假设一次性插入数据量非常大,那么能够使用  select  into  取代   create  

table ,避免造成大量   log  ,以提快速度;假设数据量不大。为了缓和系统表的资源,应先 

create table。然后insert。    





16.假设使用到了暂时表,在存储过程的最后务必将全部的暂时表显式删除,先  truncate  

table   ,然后  drop table  ,这样能够避免系统表的较长时间锁定。  





17.在全部的存储过程和触发器的開始处设置   SET   NOCOUNT   ON   ,在结束时设置   SET  

NOCOUNT OFF  。

无需在运行存储过程和触发器的每一个语句后向client发送   DONE_IN_PROC  

消息。

18.尽量避免大事务操作。提高系统并发能力。  



19.尽量避免向client返回大数据量,若数据量过大,应该考虑对应需求是否合理。  



20.  避免使用不兼容的数据类型。比如float 和int、char 和varchar 、binary 和varbinary 是不 

兼容的。

数据类型的不兼容可能使优化器无法运行一些本来能够进行的优化操作。比如:    

SELECT name FROM employee WHERE salary > 60000    

在这条语句中,如salary 字段是money 型的,则优化器非常难对其进行优化, 由于60000 是个整型 

数。我们应当在编程时将整型转化成为钱币型,而不要等到执行时转化。

21.充分利用连接条件。在某种情况下。两个表之间可能不仅仅一个的连接条件。这时在  WHERE  

子句中将连接条件完整的写上,有可能大大提高查询速度。    

例:    

SELECT SUM(A.AMOUNT) FROM ACCOUNT A,CARD B WHERE A.CARD_NO = B.CARD_NO    

SELECT  SUM(A.AMOUNT)  FROM  ACCOUNT  A,CARD  B  WHERE  A.CARD_NO  =  B.CARD_NO  AND  

A.ACCOUNT_NO=B.ACCOUNT_NO    

第二句将比第一句运行快得多。  





22、使用视图加速查询    

把表的一个子集进行排序并创建视图,有时能加速查询。它有助于避免多重排序  操作。而 

且在其它方面还能简化优化器的工作。

比如:    

SELECT cust.name,rcvbles.balance,„„other columns    

FROM cust。rcvbles    

WHERE cust.customer_id = rcvlbes.customer_id    

AND rcvblls.balance>0    

AND cust.postcode>“98000”    

ORDER BY cust.name    

假设这个查询要被运行多次而不止一次,能够把全部未付款的客户找出来放在一个视图中, 

并按客户的名字进行排序:    

CREATE VIEW DBO.V_CUST_RCVLBES    

AS    

SELECT cust.name,rcvbles.balance,„„other columns    

FROM cust。rcvbles    

WHERE cust.customer_id = rcvlbes.customer_id    

AND rcvblls.balance>0    

ORDER BY cust.name    



然后以以下的方式在视图中查询:    

SELECT   *   FROM V_CUST_RCVLBES    

WHERE postcode>“98000”    

视图中的行要比主表中的行少,并且物理顺序就是所要求的顺序,降低了磁盘I/O,所以查 

询工作量能够得到大幅降低。

23、能用DISTINCT 的就不用GROUP BY    

SELECT OrderID FROM Details WHERE UnitPrice > 10 GROUP BY OrderID    

可改为:    

SELECT DISTINCT OrderID FROM Details WHERE UnitPrice > 10  



24.能用UNION ALL 就不要用UNION    

UNION ALL 不运行SELECT DISTINCT 函数,这样就会降低非常多不必要的资源

25.尽量不要用SELECT INTO 语句。

SELECT INOT  语句会导致表锁定。阻止其它用户訪问该表。

上面我们提到的是一些主要的提高查询速度的注意事项,可是在很多其它的情况下,往往须要重复 

试验比較不同的语句以得到最佳方案。最好的方法当然是測试,看实现  同样功能的SQL 语 

句哪个运行时间最少。可是数据库中假设数据量非常少,是比較不出来的。这时能够用查看执 

行计划,即:把实现同样功能的多条SQL 语句考到  查询分析器,按CTRL+L 看查所利用的索 

引,表扫描次数(这两个对性能影响最大),整体上看询成本百分比就可以。

SQL Server 海量数据查询代码优化以及建议的更多相关文章

  1. Sql Server参数化查询之where in和like实现详解

    where in 的参数化查询实现 首先说一下我们常用的办法,直接拼SQL实现,一般情况下都能满足需要 string userIds = "1,2,3,4"; using (Sql ...

  2. 【转】Sql Server参数化查询之where in和like实现之xml和DataTable传参

    转载至: http://www.cnblogs.com/lzrabbit/archive/2012/04/29/2475427.html 在上一篇Sql Server参数化查询之where in和li ...

  3. 【转】Sql Server参数化查询之where in和like实现详解

    转载至:http://www.cnblogs.com/lzrabbit/archive/2012/04/22/2465313.html 文章导读 拼SQL实现where in查询 使用CHARINDE ...

  4. 转载 50种方法优化SQL Server数据库查询

    原文地址 http://www.cnblogs.com/zhycyq/articles/2636748.html 50种方法优化SQL Server数据库查询 查询速度慢的原因很多,常见如下几种: 1 ...

  5. SQL Server 2016 查询存储性能优化小结

    SQL Server 2016已经发布了有半年多,相信还有很多小伙伴还没有开始使用,今天我们来谈谈SQL Server 2016 查询存储性能优化,希望大家能够喜欢 作为一个DBA,排除SQL Ser ...

  6. 【转载】Sql Server参数化查询之where in和like实现详解

    文章导读 拼SQL实现where in查询 使用CHARINDEX或like实现where in 参数化 使用exec动态执行SQl实现where in 参数化 为每一个参数生成一个参数实现where ...

  7. Sql Server参数化查询之where in和like实现详解 [转]

    文章导读 拼SQL实现where in查询 使用CHARINDEX或like实现where in 参数化 使用exec动态执行SQl实现where in 参数化 为每一个参数生成一个参数实现where ...

  8. Sql Server参数化查询之where in和like实现之xml和DataTable传参 (转)

    在上一篇Sql Server参数化查询之where in和like实现详解中介绍了在Sql Server使用参数化查询where in的几种实现方案,遗漏了xml和表值参数,这里做一个补充 文章导读 ...

  9. [转]Sql Server参数化查询之where in和like实现详解

    本文转自;http://www.cnblogs.com/lzrabbit/archive/2012/04/22/2465313.html 文章导读 拼SQL实现where in查询 使用CHARIND ...

随机推荐

  1. faster rcnn结构

    rpn-data层输入的是data即整张图片,然后是根据映射生成roi框 rpn-loss-bbox输入的才是整个网络预测的roi框 bbox_transform在rpn-data层使用,把生成的ac ...

  2. 第3节 hive高级用法:15、hive的数据存储格式介绍

    hive当中的数据存储格式: 行式存储:textFile sequenceFile 都是行式存储 列式存储:orc parquet 可以使我们的数据压缩的更小,压缩的更快 数据查询的时候尽量不要用se ...

  3. 18mybatis

    18mybatis-2018/08/02 1.mybatis标签 定义SQL语句 id :唯一的标识符 parameterType:传给此语句的参数的全路径名或别名例:com.test.poso.Us ...

  4. PHP—通过HTML网页请求,PHP页面显示源码不能解析

    对于初学者来说,可能会碰到这样一个问题,那就是我们通过html网页,在表单的action中填入后台处理的php文件后,虽然可以跳转到php网页上,但是却显示一大堆php源码而不是处理请求.像这样:   ...

  5. wepy 编译警告去除办法

    如果你用过wepy打包小程序的话,那么你一定碰到了很多坑,(什么也不用说,抱一下吧)下面记录的是本人遇到的一个小坑, 编译的时候出现了黄色警告 如果你出现了上图这样的话,相信你一定也知道什么意思,就是 ...

  6. PAT 1077. 互评成绩计算

    PAT 1077. 互评成绩计算 在浙大的计算机专业课中,经常有互评分组报告这个环节.一个组上台介绍自己的工作,其他组在台下为其表现评分.最后这个组的互评成绩是这样计算的:所有其他组的评分中,去掉一个 ...

  7. 拥抱变革(More Fearless Change)

    今天从大敏捷群中了解到Tid2017的一个讲演,一位敏捷教练,组织变革的专著的作者Linda的讲演. <More Fearless Change-Strategy for Making Your ...

  8. BNUOJ 7697 Information Disturbing

    Information Disturbing Time Limit: 3000ms Memory Limit: 65536KB This problem will be judged on HDU. ...

  9. Rsync文件同步服务器配置

    rsync 是一个Unix/Linux系统下的文件同步和传输工具.rsync是用 “rsync 算法”提供了一个客户机和远程文件服务器的文件同步的快速方法.可以用来做备份或镜像.一.配置文件rsync ...

  10. msp430入门学习10

    msp430的定时器--看门狗 msp430入门学习