1.
对查询进
行
优
化,
应
尽量避免全表
扫
描,首先
应
考
虑
在
where
及
order by
涉及的列上建立索引。
2.
应
尽量避免在
where
子句中
对
字段
进
行
null
值
判断,否
则
将
导
致引擎放弃使用索引而
进
行全表
扫
描,如:
select id from t where num is null
可以在
num
上
设
置默
认值
0
,确保表中
num
列没有
null
值
,然
后
这样查询
:
select id from t where num=0
3.
应
尽量避免在
where
子句中使用
!=
或
<>
操作符,否
则
将引擎放弃使用索引而
进
行全表
扫
描。
4.
应
尽量避免在
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
5.in
和
not in
也要慎用,否
则
会
导
致全表
扫
描,如:
select id from t where num in(1,2,3)
对
于
连续
的数
值
,能用
between
就不要用
in
了:
select id from t where num between 1 and 3
6.
下面的
查询
也将
导
致全表
扫
描:
select id from t where name like '%abc%'
若要提高效率,可以考
虑
全文
检
索。
7.
如果在
where
子句中使用参数,也会
导
致全表
扫
描。因
为
SQL
只有在运行
时
才会解析局部
变
量,但
优
化程序不能将
访问计
划的
选择
推
迟
到运行
时
;它必
须
在
编译时进
行
选择
。然而,如果在
编译时
建立
访问计
划,
变
量的
值还
是未知的,因而无法作
为
索引
选择
的
输
入
项
。如下面
语
句将
进
行全表
扫
描:
select id from t where num=@num
可以改
为强
制
查询
使用索引:
select id from t with(index(
索引名
)) where num=@num
8.
应
尽量避免在
where
子句中
对
字段
进
行表达式操作,
这
将
导
致引擎放弃
使用索引而
进
行全表
扫
描。如:
select id from t where num/2=100
应
改
为
:
select id from t where num=100*2
9.
应
尽量避免在
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'
10.
不要在
where
子句中的
“=”
左
边进
行函数、算
术
运算或其他表达式运算,否
则
系
统
将可能无法正确使用索引。
11.
在使用索引字段作
为
条件
时
,如果
该
索引是复合索引,那么必
须
使用到
该
索引中的第一个字段作
为
条件
时
才能保
证
系
统
使用
该
索引,否
则该
索引将不会被使用,并且
应
尽可能的
让
字段
顺
序与索引
顺
序相一致。
12.
不要写一些没有意
义
的
查询
,如需要生成一个空表
结
构:
select col1,col2 into #t from t where 1=0
这类
代
码
不会返回任何
结
果集,但是会消耗系
统资
源的,
应
改成
这样
:
create table #t(...)
13.
很多
时
候用
exists
代替
in
是一个好的
选择
:
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)
14.
并不是所有索引
对查询
都有效,
SQL
是根据表中数据来
进
行
查询优
化的,当索引列有大量数据重复
时
,
SQL
查询
可能不会去利用索引,如一表中有字段
sex
,
male
、
female
几乎各一半,那么即使在
sex
上建了索引也
对查询
效率起不了作用。
15.
索引并不是越多越好,索引固然可以提高相
应
的
select
的效率,但同
时
也降低了
insert
及
update
的效率,因
为
insert
或
update
时
有可能会重建索引,所以怎
样
建索引需要慎重考
虑
,
视
具体情况而定。
一个表的索引数最好不要超
过
6
个,若太多
则应
考
虑
一些不常使用到的列上建的索引是否有
必要。
16.
应
尽可能的避免更新
clustered
索引数据列,因
为
clustered
索引数据列的
顺
序就是表
记录
的物理存
储顺
序,一旦
该
列
值
改
变
将
导
致整个表
记录
的
顺
序的
调
整,会耗
费
相当大的
资
源。若
应
用系
统
需要
频
繁更新
clustered
索引数据列,那么需要考
虑
是否
应
将
该
索引建
为
clustered
索引。
17.
尽量使用数字型字段,若只含数
值
信息的字段尽量不要
设计为
字符型,
这
会降低
查询
和
连
接的性能,并会增加存
储
开
销
。
这
是因
为
引擎在
处
理
查询
和
连
接
时
会逐个比
较
字符串中每一个字符,而
对
于数字型而言只需要比
较
一次就
够
了。
18.
尽可能的使用
varchar/nvarchar
代替
char/nchar
,因
为
首先
变长
字段存
储
空
间
小,可以
节
省存
储
空
间
,其次
对
于
查询
来
说
,在一个相
对较
小的字段内搜索效率
显
然要高些。
19.
任何地方都不要使用
select * from t
,用具体的字段列表代替
“*”
,不要返回用不到的任何字段。
20.
尽量使用表
变
量来代替
临时
表。如果表
变
量包含大量数据,
请
注意索引非常有限(只有主
键
索引)。
21.
避免
频
繁
创
建和
删
除
临时
表,以减少系
统
表
资
源的消耗。
22.
临时
表并不是不可使用,适当地使用它
们
可以使某些例程更有效,例如,当需要重复引用大型表或
常用表中的某个数据集
时
。但是,
对
于一次性事件,最好使用
导
出表。
23.
在新建
临时
表
时
,如果一次性插入数据量很大,那么可以使用
select into
代替
create table
,避免造成大量
log
,以提高速度;如果数据量不大,
为
了
缓
和系
统
表的
资
源,
应
先
create table
,然后
insert
。
24.
如果使用到了
临时
表,在存
储过
程的最后
务
必将所有的
临时
表
显
式
删
除,先
truncate table
,然后
drop table
,
这样
可以避免系
统
表的
较长时间锁
定。
25.
尽量避免使用游
标
,因
为
游
标
的效率
较
差,如果游
标
操作的数据超
过
1
万行,那么就
应该
考
虑
改写。
26.
使用基于游
标
的方法或
临时
表方法之前,
应
先
寻
找基于集的解决方案来解决
问题
,基于集的方法通常更有效。
27.
与
临时
表一
样
,游
标
并不是不可使用。
对
小型数据集使用
FAST_FORWARD
游
标
通常要
优
于其他逐行
处
理方法,尤其是在必
须
引用几个表才能
获
得所需的数据
时
。在
结
果集中包括
“
合
计
”
的例程通常要比使用游
标执
行的速度快。如果开
发时
间
允
许
,基于游
标
的方法和基于集的方法都可以
尝试
一下,看哪一种方法
的效果更好。
28.
在所有的存
储过
程和触
发
器的开始
处设
置
SET NOCOUNT ON
,在
结
束
时设
置
SET NOCOUNT OFF
。无需在
执
行存
储过
程和触
发
器的每个
语
句后向客
户
端
发
送
DONE_IN_PROC
消息。
29.
尽量避免大事
务
操作,提高系
统
并
发
能力。
30.
尽量避免向客
户
端返回
大数据量,若数据量
过
大,
应该
考
虑
相
应
需求是否合理。
具体的
SQL
语
句在很多情况下需要
结
合
实际
的
应
用情况来写,
这
里不作叙述
。
转载于:https://www.cnblogs.com/yjhong2001/archive/2009/09/05/1560946.html