数据库SQL调优的⼏种⽅式
创建索引
尽量避免全表扫描,⾸先应考虑在 where 及 order by 涉及的列上建⽴索引
索引太多会降低 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑
避免在索引上使⽤计算
在where字句中,如果索引列是计算或者函数的⼀部分,DBMS的优化器将不会使⽤索引⽽使⽤全表查询,函数属于计算的⼀种,同时在in和exists中通常情况下使⽤EXISTS,因为in不⾛索引
效率低:
select* from user where salary*22>11000(salary是索引列)
效率⾼:
select* from user where salary>11000/22(salary是索引列)
使⽤预编译查询
程序中通常是根据⽤户的输⼊来动态执⾏SQL,这时应该尽量使⽤参数化SQL,这样不仅可以避免SQL注⼊漏洞攻击。
最重要数据库会对这些参数化SQL进⾏预编译,这样第⼀次执⾏的时候DBMS会为这个SQL语句进⾏查询优化并且执⾏预编译,这样以后再执⾏这个SQL的时候就直接使⽤预编译的结果,这样可以⼤⼤提⾼执⾏的速度。
调整Where字句中的连接顺序
DBMS⼀般采⽤⾃下⽽上的顺序解析where字句,那些可以过滤掉最⼤数量记录最好写在其他where条件之前。
尽量将多条SQL语句压缩到⼀句SQL中
每次执⾏SQL的时候都要建⽴⽹络连接、进⾏权限校验、进⾏SQL语句的查询优化、发送执⾏结果,这个过程是⾮常耗时的,因此应该尽量避免过多的执⾏SQL语句,能够压缩到⼀句SQL执⾏的语句就不要⽤多条来执⾏。
⽤where字句替换HAVING字句
避免使⽤HAVING字句,因为HAVING只会在检索出所有记录之后才对结果集进⾏过滤,⽽where则是在聚合前刷选记录,如果能通过where字句限制记录的数⽬,那就能减少这⽅⾯的开销。
HAVING中的条件⼀般⽤于聚合函数的过滤。
使⽤表的别名
当在SQL语句中连接多个表时,请使⽤表的别名并把别名前缀于每个列名上。这样就可以减少解析的时间并减少哪些友列名歧义引起的语法错误。
⽤union all替换union
当SQL语句需要union两个查询结果集合时,即使检索结果中不会有重复的记录,如果使⽤union这两个结果集同样会尝试进⾏合并,然后在输出最终结果前进⾏排序,因此如果可以判断检索结果中不会有重复的记录时候,应该⽤union all,这样效率就会因此得到提⾼。
考虑使⽤“临时表”暂存中间结果
简化SQL语句的重要⽅法就是采⽤临时表暂存中间结果,但是,临时表的好处远远不⽌这些,将临时结果暂存在临时表,后⾯的查询就在tempdb中了,这可以避免程序中多次扫描主表,也⼤⼤减少了程序执⾏中“共享锁”阻塞“更新锁”,减少了阻塞,提⾼了并发性能。
但是也得避免频繁创建和删除临时表,以减少系统表资源的消耗。
只在必要的情况下才使⽤事务begin translation
SQL Server中⼀句SQL语句默认就是⼀个事务,在该语句执⾏完成后也是默认commit的。其实,这就是begin tran的⼀个最⼩化的形式,好⽐在每句语句开头隐含了⼀个begin tran,结束时隐含了⼀个commit。
有些情况下,我们需要显式声明begin tran,⽐如做“插、删、改”操作需要同时修改⼏个表,要求要么⼏个表都修改成功,要么都不成功。begin tran 可以起到这样的作⽤,它可以把若⼲SQL语句套在⼀起执⾏,最后再⼀起commit。 好处是保证了数据的⼀致性,但任何事情都不是完美⽆缺的。Begin tran付出的代价是在提交之前,所有SQL语句锁住的资源都不能释放,直到commit掉。
如果Begin tran套住的SQL语句太多,那数据库的性能就糟糕了。在该⼤事务提交之前,必然会阻塞别的语句,造成block很多。
Begin tran使⽤的原则是,在保证数据⼀致性的前提下,begin tran 套住的SQL语句越少越好!有些情况下可以采⽤触发器同步数据,不⼀定要⽤begin tran。
尽量避免使⽤游标
尽量避免向客户端返回⼤数据量,若数据量过⼤,应该考虑相应需求是否合理。因为游标的效率较差,如果游标操作的数据超过1万⾏,那么就应该考虑改写。
⽤varchar/nvarchar 代替 char/nchar
尽可能的使⽤ varchar/nvarchar 代替 char/nchar ,因为⾸先变长字段存储空间⼩,可以节省存储空间,其次对于查询来说,在⼀个相对较⼩的字段内搜索效率显然要⾼些。
不要以为 NULL 不需要空间,⽐如:char(100) 型,在字段建⽴时,空间就固定了, 不管是否插⼊值(NULL也包含在内),都是占⽤ 100个字符的空间的,如果是varchar这样的变长字段, null 不占⽤空间。
查询select语句优化
任何地⽅都不要使⽤ select * from t ,⽤具体的字段列表代替“*”,不要返回⽤不到的任何字段
应尽量避免在 where ⼦句中对字段进⾏ null 值判断,否则将导致引擎放弃使⽤索引⽽进⾏全表扫描
select id from t where num is null
更新Update语句优化
如果只更改1、2个字段,不要Update全部字段,否则频繁调⽤会引起明显的性能消耗,同时带来⼤量⽇志
删除Delete语句优化语句
sql语句优化方式
最⾼效的删除重复记录⽅法 ( 因为使⽤了ROWID)例⼦
DELETE FROM EMP E WHERE E.ROWID >(SELECT MIN(X.ROWID) FROM EMP X WHERE X.EMP_NO = E.EMP_NO);
插⼊Insert语句优化
在新建临时表时,如果⼀次性插⼊数据量很⼤,那么可以使⽤ select into 代替 create table,避免造成⼤量 log ,以提⾼速度如果数据量不⼤,为了缓和系统表的资源,应先create table,然后insert

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。