菜单

浅谈MySQL中优化sql语句询问常用的30栽艺术

2018年11月16日 - MySQL

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

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

2、许尽量避免在 where
子句被使!=或<>操作符,否则用引擎放弃采用索引而展开全表扫描。 

2.答应竭尽避免以 where
子句被采用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。

3、许尽量避免在 where 子句被针对字段进行 null
值判断,否则将造成发动机放弃使用索引而进行全表扫描,如: 
select id from t where num is null 
好当num上安默认值0,确保表中num列没有null值,然后这样查询: 
select id from t where num=0 

3.应尽可能避免以 where 子句被针对字段进行 null
值判断,否则用致发动机放弃行使索引而展开全表扫描,如:
select id from t where num is null
足于num上安装默认值0,确保表中num列没有null值,然后这样查询:
select id from t where num=0

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 

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、下面的询问也将促成全表扫描: 
select id from t where name like ‘%abc%’ 
一旦要提高效率,可以考虑全文检索。 

5.下面的查询也拿招致全表扫描:
select id from t where name like ‘%abc%’
只要要提高效率,可以设想全文检索。

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 

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

7、万一以 where
子句被利用参数,也会见招全表扫描。因为SQL只出以运行时才见面分析局部变量,但优化程序不能够用拜访计划的抉择推迟到运行时;它要以编译时展开选。然而,如果在编译时确立访问计划,变量的价还是大惑不解的,因而无法作为目录选择的输入项。如下面语句以进行全表扫描: 
select id from t where num=@num 
可变动呢要挟查询利用索引: 
select id from t with(index(索引名)) where num=@num 

7.如果在 where
子句被使参数,也会造成全表扫描。因为SQL只发生在运转时才会分析局部变量,但优化程序不可知拿造访计划的选项推迟至运行时;它必须于编译时开展分选。然而,如果以编译时确立访问计划,变量的价值还是大惑不解之,因而无法作为目录选择的输入项。如下面语句以开展全表扫描:
select id from t where
[email protected]
足转吧强制查询利用索引:
select id from t with(index(索引名)) where
[email protected]

8、许尽量避免在 where
子句被对字段进行表达式操作,这将造成发动机放弃下索引而展开全表扫描。如: 
select id from t where num/2=100 
应改为: 
select id from t where num=100*2 

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’ 

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
子句被之“=”左边进行函数、算术运算或另表达式运算,否则系统以可能无法正确用索引。 

10.决不在 where
子句被之“=”左边进行函数、算术运算或另表达式运算,否则系统将可能无法对用索引。

11、当以索引字段作为条件时,如果该索引是复合索引,那么得用到该索引中之首先只字段作为规范时才能够保证系统使用该索引,否则该索引将未会见被下,并且应尽量的叫字段顺序与索引顺序相平等。 

11.当动用索引字段作为基准时,如果该索引是复合索引,那么必须用到该索引中之率先个字段作为标准时才能够保证系统使用该索引,否则该索引将非会见叫下,并且应竭尽的让字段顺序及索引顺序相平等。

12、不用写一些没有意思之询问,如要好成一个空表结构: 
select col1,col2 into #t from t where 1=0 
当时看似代码不见面回到外结果集,但是会消耗系统资源的,应改变成为这样: 
create table #t(…) 

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) 

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上建筑了目录也对查询效率起不了打算。 

14.并无是兼备索引对查询都有效,SQL是基于表中数据来展开查询优化的,当索引列有恢宏数码重复时,SQL查询可能无见面失去采用索引,如一表中出字段sex,male、female几乎各个一半,那么即使以sex上构筑了目录也本着查询效率起不了企图。

15、目录并无是越多越好,索引固然好增长相应的 select
的频率,但同时为落了 insert 及 update 的效率,因为 insert 或 update
时产生或会见重建索引,所以什么建索引需要慎重考虑,视具体情况而得。一个发明底索引数最好不要超过6个,若太多则承诺考虑有不常使用及之列上建之目录是否出必要。 

15.索惹并无是越多越好,索引固然好增进相应的 select
的频率,但还要为跌了 insert 及 update 的效率,因为 insert 或 update
时来或会见重建索引,所以哪建索引需要慎重考虑,视具体情况而得。一个说明的索引数最好不要跨越6只,若太多则应考虑部分不常使用及之列上建之目是否发生必要。

16、答应尽量的免更新 clustered 索引数据列,因为 clustered
索引数据列的依次就是表明记录之大体存储顺序,一旦该列值改变将促成整表记录之相继的调,会耗费一定深的资源。若采用体系要频繁更新
clustered 索引数据列,那么用考虑是不是应将该索引建为 clustered 索引。 

16.许尽可能的免更新 clustered 索引数据列,因为 clustered
索引数据列的逐一就是说明记录之大体存储顺序,一旦该列值改变将导致整个表记录之逐条的调,会损耗一定深的资源。若用体系要频繁更新
clustered 索引数据列,那么用考虑是不是应拿该索引建为 clustered 索引。

17、尽心尽力采取数字型字段,若只有包含数值信息之字段尽量不要设计也字符型,这会降查询与连的性,并会见增多存储开销。这是坐引擎在处理查询以及连时会相继个比字符串中各一个字符,而对数字型而言就需要比一致不成就是足足了。 

17.尽量运用数字型字段,若只有包含数值信息之字段尽量不要设计也字符型,这会降查询与连的性,并会见增多存储开销。这是因引擎在处理查询以及连续时会相继个比字符串中各一个字符,而对数字型而言就需要比一致不良就是够用了。

18、尽可能的应用 varchar/nvarchar 代替 char/nchar
,因为首先变长字段存储空间小,可以省去存储空间,其次对于查询来说,在一个对立比较小的字段内搜索频率显著要后来居上数。 

18.尽可能的用 varchar/nvarchar 代替 char/nchar
,因为首先变长字段存储空间稍加,可以节约存储空间,其次对于查询来说,在一个针锋相对较小之字段内寻找频率明显要高数。

19、其它地方都不要使用 select * from t
,用现实的字段列表代替“*”,不要回来用非顶之另字段。 

19.旁地方还毫无使 select * from t
,用现实的字段列表代替“*”,不要回来用不至之其它字段。

20、尽心尽力采用表变量来替临时表。如果表变量包含大量数码,请留意索引非常有限(只有主键索引)。 

20.尽量动表变量来顶替临时表。如果表变量包含大量数量,请小心索引非常有限(只有主键索引)。

21、避免频繁创建与去临时表,以缩减系统表资源的消耗。 

21.免频繁创建同去临时表,以减掉系统表资源的损耗。

22、临时表并无是不可采用,适当地利用她得以要某些例程更实惠,例如,当需要再次引用大型表或常用表中的某部数集时。但是,对于一次性事件,最好以导出表。 

22.临时表并无是不行下,适当地以它可使少数例程更管用,例如,当用再次引用大型表或常用表中的某部数集时。但是,对于一次性事件,最好使用导出表。

23、在新建临时表时,如果一次性插入数据量很挺,那么可以运用 select
into 代替 create table,避免造成大气 log
,以增进速度;如果数据量不雅,为了缓和系统表的资源,应先create
table,然后insert。 

23.当新建临时表时,如果一次性插入数据量很十分,那么可采取 select into
代替 create table,避免造成大量 log
,以增强速度;如果数据量不特别,为了降温系统表的资源,应先create
table,然后insert。

24、要下到了临时表,在储存过程的最终得将具备的临时表显式删除,先
truncate table ,然后 drop table ,这样好避系统表的较长时间锁定。 

24.只要采用及了临时表,在储存过程的结尾得将兼具的临时表显式删除,先
truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。

25、尽量避免使用游标,因为游标的效率比较差,如果游标操作的数量超过1万履,那么就应当考虑改写。 

25.尽量避免使用游标,因为游标的频率比差,如果游标操作的多少超过1万推行,那么就是相应考虑改写。

26、采取基于游标的道或者临时表方法之前,应先行找基于集的化解方案来缓解问题,基于集的艺术一般还实用。 

26.用到基于游标的方式要临时表方法之前,应事先物色基于集的化解方案来化解问题,基于集的办法一般还实惠。

27、跟临时表一样,游标并无是不足使用。对袖珍数据集使用 FAST_FORWARD
游标通常如果优惠其他逐行处理措施,尤其是以必得引用几单说明才能够赢得所用的多少经常。在结果集中包括“合计”的例程通常要于下游标执行之快慢快。如果开发时间允许,基于游标的主意与根据集的法门还足以尝尝一下,看啦一样种植方法的效用还好。 

27.与临时表一样,游标并无是不行使用。对袖珍数据集使用 FAST_FORWARD
游标通常如果优惠其他逐行处理办法,尤其是于得引用几独说明才能够取得所用的数据经常。在结果集中包括“合计”的例程通常要比较采用游标执行之速快。如果开发时间允许,基于游标的方以及基于集的法还足以品尝一下,看啦一样种植办法的功用更好。

28、当颇具的储存过程与触发器的开处于安装 SET NOCOUNT ON
,在截止时设置 SET NOCOUNT OFF
。无需在执行存储过程和触发器的每个语句后朝着客户端发送 DONE_IN_PROC
消息。 

28.每当具备的储存过程和触发器的开端处于安装 SET NOCOUNT ON ,在终结时设置
SET NOCOUNT OFF 。无需以实施存储过程和触发器的每个语句后朝客户端发送
DONE_IN_PROC 消息。

29、尽量避免向客户端返回大数据量,若数据量过怪,应该考虑相应要求是否站得住。 

29.尽量避免向客户端返回大数据量,若数据量过十分,应该考虑相应要求是否合理。

30、尽量避免大事务操作,提高系统出现能力。**

30.尽量避免大事务操作,提高系统出现能力。

当网上发现了同样首好之稿子,但笔者不详,就厚着脸皮扒过来了,仅作个人学习下

http://www.bkjia.com/Mysql/352464.htmlwww.bkjia.comtruehttp://www.bkjia.com/Mysql/352464.htmlTechArticle1.对查询进行优化,应尽量避免全表扫描,首先应考虑在
where 及 order by 涉及的列上建立目录。 2.承诺竭尽避免以 where
子句被运用!=或操作符,…

相关文章

发表评论

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

网站地图xml地图