菜单

MySQL 常用30种SQL查询语句优化措施

2019年2月28日 - sqlite

20、尽或然使用表变量来代替一时表。假设表变量包蕴大批量数据,请留心索引非凡不难(唯有主键索引)。 

18、尽或许的利用 varchar/nvarchar 代替 char/nchar
,因为首先变长字段存款和储蓄空间小,能够节省存款和储蓄空间,其次对于查询来说,在1个冲突较小的字段内搜索频率肯定要高些。 

三 、应尽量幸免在 where 子句中对字段进行 null
值判断,不然将造成斯特林发动机吐弃选用索引而实行全表扫描。如:

**1、对查询进行优化,应尽量幸免全表扫描,首先应考虑在
where 及 order by 涉及的列上建立目录。 

11

15、目录并不是更加多越好,索引就算能够升高相应的 select
的频率,但还要也暴跌了 insert 及 update 的效用,因为 insert 或 update
时有只怕会重建索引,所以什么建索引需求三思而行,视具体情状而定。3个表的索引数最好不要跨越四个,若太多则应考虑部分不常使用到的列上建的目录是不是有必不可少。 

select id from t where

27、与暂时表一样,游标并不是不可采纳。对小型数据集使用 FAST_FO帕杰罗WALANDD
游标日常要优惠其他逐行处理方法,尤其是在必得引用多少个表才能获得所需的数码时。在结果集中包涵“合计”的例程平时要比接纳游标执行的快慢快。就算开发时间允许,基于游标的主意和基于集的主意都足以尝试一下,看哪个种类艺术的功力更好。 

1柒 、尽量利用数字型字段,若只含数值音讯的字段尽量不要设计为字符型,这会稳中有降查询和三番五次的性质,并会增多存款和储蓄花费。那是因为引擎在处理查询和接二连三时会
每个比较字符串中每叁个字符,而对于数字型而言只必要对比一回就够了。

16、应竭尽的防止更新 clustered 索引数据列,因为 clustered
索引数据列的相继正是表记录的情理存款和储蓄顺序,一旦该列值改变将导致整个表记录的一一的调整,会损耗一定大的资源。若使用系统须要频仍更新
clustered 索引数据列,那么要求考虑是不是应将该索引建为 clustered 索引。 

那类代码不会重临任何结果集,然而会消耗系统财富的,应改成这样:

30、尽量防止大事务操作,进步系统出现能力。**

select id from t where num=20

5、上面包车型客车询问也将造成全表扫描: 
select id from t where name like ‘%abc%’ 
若要提升成效,能够考虑全文字笔迹检验索。 

1② 、不要写一些从未意思的询问,如必要生成三个空表结构:

2、应尽量防止在 where
子句中运用!=或<>操作符,不然将引擎屏弃行使索引而实行全表扫描。 

20、尽量使用表变量来取代如今表。就算表变量包涵大批量数目,请小心索引格外有限(唯有主键索引)。

在网上发现了一篇好的小说,但笔者不详,就厚着脸皮扒过来了,仅作个人学习运用

create table #t(…)

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 

2二 、方今表并不是不可利用,适当地应用它们能够使一些例程更使得,例如,当需求再行引用大型表或常用表中的某部数据集时。不过,对于2遍性事件,较好使
用导出表。

14、并不是兼具索引对查询都有效,SQL是基于表中数据来展开查询优化的,当索引列有大气数额再次时,SQL查询大概不会去采用索引,如一表中有字段sex,male、female大约各四分之二,那么固然在sex上建了目录也对查询作用起绵绵成效。 

27、与如今表一样,游标并不是不行动用。对微型数据集使用 FAST_FO汉兰达WA哈弗D
游标平常要优于其余逐行处理措施,越发是在必得引用多少个表才能博得所需的多寡时。在结果集中包罗“合计”的例程平时要比采纳游标执行的进程快。要是开发时
间允许,基于游标的不二法门和根据集的不二法门都足以品尝一下,看哪种办法的效果更好。

21、制止频仍创制和删除一时半刻表,以压缩系统表能源的费用。 

select id from t where num=100*2

6、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 

2六 、使用基于游标的法门或目前表方法在此之前,应先物色基于集的缓解方案来消除难点,基于集的措施一般更实用。

24、设若应用到了一时半刻表,在储存进程的末梢务必将具有的最近表显式删除,先
truncate table ,然后 drop table ,那样能够幸免系统表的较长期锁定。 

select id from t where num/2=100

25、尽量制止使用游标,因为游标的成效较差,假如游标操作的数据当先1万行,那么就应该考虑改写。 

1壹 、在动用索引字段作为条件时,假诺该索引是复合索引,那么必须选择到该索引中的第①个字段作为基准时才能保障系统使用该索引,不然该索引将不会被使
用,并且应尽只怕的让字段顺序与索引顺序相平等。

11、在应用索引字段作为基准时,假设该索引是复合索引,那么必须选取到该索引中的第一个字段作为条件时才能有限帮衬系统使用该索引,不然该索引将不会被使用,并且应尽量的让字段顺序与索引顺序相平等。 

用上面包车型地铁讲话替换:

10、并非在 where
子句中的“=”左侧进行函数、算术运算或其余表达式运算,不然系统将可能不可能正确使用索引。 

四 、尽量制止在 where 子句中运用 or
来连接条件,不然将招致汽油发动机放任行使索引而进展全表扫描,如:

19、任何地方都毫无使用 select * from t
,用现实的字段列表代替“*”,不要回来用不到的其他字段。 

select id from t where substring(name,1,3

17、尽可能采纳数字型字段,若只含数值音信的字段尽量不要设计为字符型,那会下滑查询和连续的属性,并会追加存储费用。那是因为引擎在处理查询和接二连三时会各个比较字符串中每2个字符,而对于数字型而言只须求相比较三遍就够了。 

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

7、若是在 where
子句中使用参数,也会招致全表扫描。因为SQL唯有在运行时才会分析局地变量,但优化程序不能够将做客布署的取舍推迟到运维时;它必须在编写翻译时开始展览选取。不过,假诺在编写翻译时确立访问安插,变量的值还是大惑不解的,由此无法作为目录选取的输入项。如下边语句将实行全表扫描: 
select id from t where num=@num 
可以改为威胁查询利用索引: 
select id from t with(index(索引名)) where num=@num 

2005

28、在全数的囤积进度和触发器的上马处安装 SET NOCOUNT ON
,在终结时设置 SET NOCOUNT OFF
。无需在执行存储进程和触发器的种种语句后向客户端发送 DONE_IN_PROC
消息。 

下边走索引

29、尽量制止向客户端再次来到大数据量,若数据量过大,应该考虑相应须求是或不是合理。 

若要升高成效,能够设想全文字笔迹检验索。

23、在新建一时半刻表时,假若1回性插入数据量十分的大,那么能够运用 select
into 代替 create table,防止造成大气 log
,以增速;假若数据量十分的小,为了缓和系统表的能源,应先create
table,然后insert。 

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

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) 

′)=

26、使用基于游标的法子或暂时表方法以前,应先找找基于集的缓解方案来化解难题,基于集的点子一般更实用。 

能够改为威吓查询利用索引:

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’ 

2八 、在颇具的存款和储蓄进度和触发器的起来处安装 SET NOCOUNT ON ,在得了时设置
SET NOCOUNT OFF 。无需在推行存款和储蓄进程和触发器的种种语句后向客户端发送
DONEINPROC 新闻。

3、应尽量幸免在 where 子句中对字段进行 null
值判断,不然将造成斯特林发动机放任行使索引而举办全表扫描,如: 
select id from t where num is null 
能够在num上安装暗许值0,确定保障表中num列没有null值,然后那样查询: 
select id from t where num=0 

1八 、尽大概的施用 varchar/nvarchar 代替 char/nchar
,因为首先变长字段存款和储蓄空间小,能够节省存款和储蓄空间,其次对于查询来说,在2个相持较小的字段内搜索频率分明要高些。

12、决不写一些并未意义的查询,如供给生成二个空表结构: 
select col1,col2 into #t from t where 1=0 
那类代码不会再次回到任何结果集,不过会损耗系统财富的,应改成这么: 
create table #t(…) 

贰 、对查询举行优化,应尽量防止全表扫描,首先应考虑在 where 及 order by
涉及的列上建立目录。

22、近期表并不是不足采取,适当地利用它们能够使少数例程更实惠,例如,当须求再一次引用大型表或常用表中的有些数据集时。不过,对于3回性事件,最好使用导出表。 

应改为:

0

 datediff(day,createdate,’

select id from t where num=@num

① 、应尽量防止在 where
子句中应用!=或<>操作符,不然将引擎放弃使用索引而进行全表扫描。

1三 、很多时候用 exists 代替 in 是二个好的挑三拣四:

1⑨ 、任啥地点方都毫无使用 select * from t
,用现实的字段列表代替“*”,不要回来用不到的任何字段。

能够在num上安装暗中同意值0,确定保障表中num列没有null值,然后那样查询:

select id from t where num between 1 and 3

对此连日来的数值,能用 between 就不用用 in 了:

select col1,col2 into #t from t where 1=0

–’

16.应竭尽的制止更新 clustered 索引数据列,因为 clustered
索引数据列的逐一正是表记录的情理存款和储蓄顺序,一旦该列值改变将招致整个表记录的各种的调动,会损耗一定大的能源。若选拔类别供给反复更新
clustered 索引数据列,那么需求考虑是否应将该索引建为 clustered 索引。

30

1肆 、并不是颇具索引对查询都灵验,SQL是基于表中数据来展开查询优化的,当索引列有大量数目再度时,SQL查询大概不会去行使索引,如一表中有字段
sex,male、female大约各50%,那么固然在sex上建了目录也对查询功效起绵绵功效。

select id from t where num=10

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

30、尽量幸免大事务操作,进步系统出现能力。

十 、不要在 where
子句中的“=”左侧实行函数、算术运算或其他表明式运算,不然系统将恐怕不能正确运用索引。

select id from t where num=10 or num=20

union all

⑦ 、若是在 where
子句中运用参数,也会招致全表扫描。因为SQL唯有在运维时才会分析局地变量,但优化程序不可能将做客陈设的选料推迟到运营时;它必须在编写翻译时举行精选。然则,如若在编写翻译时确立访问陈设,变量的值仍然大惑不解的,因此不可能作为目录选用的输入项。如上边语句将拓展全表扫描:

select id from t where num is null

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

select id from t where name like ‘%c%’

八 、应尽量制止在 where
子句中对字段进行表明式操作,那将招致汽油发动机甩掉使用索引而开展全表扫描。如:

2⑨ 、尽量防止向客户端重返大数据量,若数据量过大,应该考虑相应必要是或不是合理。

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

陆 、in 和 not in 也要慎用,不然会促成全表扫描,如:

30

select id from t where num=0

select id from t where name like ‘abc%’

2三 、在新建权且表时,如若一遍性插入数据量不小,那么能够选取 select into
代替 create table,幸免造成大批量 log
,以增强速度;假诺数据量十分的小,为了温度下落系统表的财富,应先create
table,然后insert。

五 、下边包车型大巴询问也将造成全表扫描:(不能放手百分号)

应改为:

′生成的id

1⑤ 、索引并不是更多越好,索引固然能够增强相应的 select
的频率,但同时也降低了 insert 及 update 的作用,因为 insert 或 update
时有恐怕会重建索引,所以怎么建索引供给稳扎稳打,视具体意况而定。三个表的索引数较好永不跨越四个,若太多则应考虑部分不常使用到的列上建的目录是或不是有
要求。

select id from t where name like ‘c%’

2005

2肆 、假设采用到了近期表,在储存进程的最终务必将具备的一时表显式删除,先
truncate table ,然后 drop table ,那样能够制止系统表的较长期锁定。

九 、应尽量防止在where子句中对字段实行函数操作,那将导致电动机放任行使索引而进展全表扫描。如:

11

2伍 、尽量防止使用游标,因为游标的频率较差,假若游标操作的数额超过1万行,那么就应有考虑改写。

2① 、制止频仍成立和删除权且表,以缩减系统表能源的消耗。

)=’abc’–name以abc开头的id

@作品来源:ITPUB

能够如此查询:

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图