数据库SQL调优的几种方式

在项目中,SQL的调优对项目的性能来说相当重要,全部掌握常见的SQL调优方式是必不可少的,下面介绍几种常见的SQL的调优方式,供借鉴.数据库

一.建立索引
1.要尽可能避免全表扫描,首先应考虑在 where 及 order by 涉及的列上创建索引 
2.(1)在常常须要进行检索的字段上建立索引,好比要按照表字段username进行检索,那么就应该在姓名字段上建立索引,若是常常要按照员工部门和员工岗位级别进行检索,那么就应该在员工部门和员工岗位级别这两个字段上建立索引。 
(2)建立索引给检索带来的性能提高每每是巨大的,所以在发现检索速度过慢的时候应该首先想到的就是建立索引。 
(3)一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有 必要。索引并非越多越好,索引当然能够提升相应的 select 的效率,但同时也下降了 insert 及 update 的效率,由于 insert 或 update 时有可能会重建索引,因此怎样建索引须要慎重考虑,视具体状况而定。网络

二.避免在索引上使用计算
在where字句中,若是索引列是计算或者函数的一部分,DBMS的优化器将不会使用索引而使用全表查询,函数 
属于计算的一种,同时在in和exists中一般状况下使用EXISTS,由于in不走索引 
效率低:并发

 select * from user where salary*22>11000(salary是索引列)
1
效率高:函数

 select * from user where salary>11000/22(salary是索引列)
1
三.使用预编译查询
程序中一般是根据用户的输入来动态执行SQL,这时应该尽可能使用参数化SQL,这样不只能够避免SQL注入漏洞 
攻击,最重要数据库会对这些参数化SQL进行预编译,这样第一次执行的时候DBMS会为这个SQL语句进行查询优化 
而且执行预编译,这样之后再执行这个SQL的时候就直接使用预编译的结果,这样能够大大提升执行的速度。性能

四.调整Where字句中的链接顺序
DBMS通常采用自下而上的顺序解析where字句,根据这个原理表链接最好写在其余where条件以前,那些能够 
过滤掉最大数量记录。大数据

五.尽可能将多条SQL语句压缩到一句SQL中
每次执行SQL的时候都要创建网络链接、进行权限校验、进行SQL语句的查询优化、发送执行结果,这个过程 
是很是耗时的,所以应该尽可能避免过多的执行SQL语句,可以压缩到一句SQL执行的语句就不要用多条来执行。优化

六.用where字句替换HAVING字句
避免使用HAVING字句,由于HAVING只会在检索出全部记录以后才对结果集进行过滤,而where则是在聚合前 
刷选记录,若是能经过where字句限制记录的数目,那就能减小这方面的开销。HAVING中的条件通常用于聚合函数 
的过滤,除此以外,应该将条件写在where字句中。日志

七.使用表的别名
当在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语句优化
1.任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段 
2.应尽可能避免在 where 子句中对字段进行 null 值判断,不然将致使引擎放弃使用索引而进行全表扫描, 
如:

     select id from t where num is null           
1
能够在num上设置默认值0,确保表中num列没有null值, 
而后这样查询:

      select id from t where num=0
      select id from t where num=10 or num=20
1
2
能够这样查询:

      select id from t where num=10
       union all
      select id from t where num=20
1
2
3
4.不能前置百分

select id from t where name like ‘%abc%’
1
若要提升效率,能够考虑全文检索。

     select id from t where num in(1,2,3)
1
对于连续的数值,能用 between 就不要用 in 了:

    select id from t where num between 1 and 3 
1
6.若是查询的两个表大小至关,那么用in和exists差异不大。 
in: 
例如:表A(小表),表B(大表)

 select * from A where cc in (select cc from B) 效率低,用到了A表上cc列的索引;     
 select * from A where exists(select cc from B where cc=A.cc)   效率高,用到了B表上cc列的索引。   
1
2
相反的

 select * from B where cc in (select cc from A)  效率高,用到了B表上cc列的索引;
 select * from B where exists(select cc from A where cc=B.cc)  效率低,用到了A表上cc列的索引。         
1
2
十四.更新Update语句优化
1.若是只更改一、2个字段,不要Update所有字段,不然频繁调用会引发明显的性能消耗,同时带来大量日志

十五. 删除Delete语句优化语句
1.最高效的删除重复记录方法 ( 由于使用了ROWID)例子:

DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID) FROM EMP X WHERE X.EMP_NO = E.EMP_NO); 1 十六.插入Insert语句优化 1.在新建临时表时,若是一次性插入数据量很大,那么可使用 select into 代替 create table,避免形成大量 log ,以提升速度;若是数据量不大,为了缓和系统表的资源,应先create table,而后insert。

相关文章
相关标签/搜索