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. CREATE SCHEMA - 定义一个新的模式

    SYNOPSIS CREATE SCHEMA schemaname [ AUTHORIZATION username ] [ schema_element [ ... ] ] CREATE SCHEM ...

  2. caffe编译

    用make -j带一个参数,可以把项目在进行并行编译,比如在一台双核的机器上,完全可以用make -j4,让make最多允许4个编译命令同时执行,这样可以更有效的利用CPU资源 也就是说make -j ...

  3. pytorch: Variable detach 与 detach_

    pytorch 的 Variable 对象中有两个方法,detach和 detach_ 本文主要介绍这两个方法的效果和 能用这两个方法干什么. detach 官方文档中,对这个方法是这么介绍的. 返回 ...

  4. 零基础入门学习Python(23)--递归:这帮小兔崽子

    知识点 我们都知道兔子繁殖能力是惊人的,如下图: 我们可以用数学函数来定义: 假设我们需要求出经历了20个月后,总共有多少对小兔崽子? 迭代实现 def fab(n): n1 = 1 n2 = 1 n ...

  5. C语言学习1

    一.初识C语言 1.1 C语言的起源 1972年,贝尔实验室的丹尼斯,里奇和肯,汤普逊在开发UNIX操作系统时设计了C语言,然而,C语言不完全是里奇突发奇想出来的,他是在B语言的基础上进行设计的,至于 ...

  6. 97-2016年11月1日AUDUSD在公布利率后反手做单感悟(2016.11.2)

    2016年11月1日AUDUSD在公布利率后反手做单感悟         11月1日,澳联储公布利率决议,保持利率不变,AUDUSD大涨.我在上面做空认为市场会回调.做空位置是根据多种斐波那契技术找的 ...

  7. echarts的简单应用之(二)饼图

    接上一篇文章: echarts的简单应用之(一)柱形图:https://www.cnblogs.com/jylee/p/9359363.html 本篇文章讲述饼图,撇过折线图不说,是因为折线图与柱形图 ...

  8. 【转】WEB前端调优

    首先从一次完整的的请求说起:(以此为例get,www,baidu.com) 1,webbrower 发出request, 2,然后解析www.baidu.com为ip,找到ip的服务器, 3,服务器处 ...

  9. mysql和Oracle 备份表

    1.SQL Server中,如果目标表存在: insert into 目标表 select * from 原表; 2.SQL Server中,,如果目标表不存在: select * into 目标表  ...

  10. vagrant的学习 之 ThinkPHP5.1

    vagrant的学习 之 ThinkPHP5.1 本文根据慕课网的视频教程练习,感谢慕课网! 慕课视频学习地址:https://www.imooc.com/video/14218. 慕课的参考文档地址 ...