sql 语句性能调优

数据库性能问题:非常低的并发,令人崩溃的响应时间,长时间的锁等待,锁升级 , 甚至是死锁,等等

“根据我们的经验(由很多业界专家证明),在 SQL Server 上取得的性能提高有 80% 来自对 SQL 编码的改进,而不是来自于对于配置或系统性能的调整。”
—凯文 克莱恩等,Transact-SQL Programming 作者

“经验表明 80%-90% 的性能调优是在应用级做的,而不是在数据库级”
—托马斯 白特,Expert One on One: Oracle 作者

 1.根据权重来优化查询条件

sql 语句性能调优

2.针对专门操作符的调优

and

数据库系统按着从左到右的顺序来解析一个系列由 AND 连接的表达式,但是 Oracle 却是个例外,它是从右向左地解析表达式。

可以利用数据库系统的这一特性,来将概率小的表达示放在前面,或者是如果两个表达式可能性相同,那么可将相对不复杂的表达式放在前面。

这样做的话,如果第一个表达式为假的话,那么数据库系统就不必再费力去解析第二个表达式了。

总之

用and时

直接的        把搜索出来数据比较少的放在前面,这样再在搜索出来的基础上进行搜索比较容易。

表达式的    把表达式比较简单的放在前面,这样假如没有数据,就不用再执行后面复杂的表达式了。

在oracle中这种情况就相反。

or

or的情况与and的正好相反

 

not

让非 (NOT) 表达示转换成更易读的形式。

... WHERE NOT (column1 > 5) 

 

转换成:

 ... WHERE column1 <= 5 

 

IN

很多人认为如下的两个查询条件没有什么差别,因为它们返回的结果集是相同的:

条件 1:

 ... WHERE column1 = 5 

 OR column1 = 6 

条件 2:

 ... WHERE column1 IN (5, 6) 

这样的想法并不完全正确,对于大多数的数据库操作系统来说,IN 要比 OR 执行的快。所以如果可以的话,要将 OR 换成 IN

当 IN 操作符,是一系列密集的整型数字时,最好是查找哪些值不符合条件,而不是查找哪些值符合条件。

经常用not in

查询符合条件的in时,效率不高,要对其进行优化

 ... WHERE column1 IN (1, 3, 4, 5) 

 

转换成:

 ... WHERE column1 BETWEEN 1 AND 5 
 AND column1 <> 2 

 in适合用于in内部数据比较少的情况。

select * from A where id in(select id from B)

它的查询过程类似于以下过程

List resultSet=[];
Array A=(select * from A);
Array B=(select id from B);

for(int i=0;i<A.length;i++) {
   for(int j=0;j<B.length;j++) {
      if(A[i].id==B[j].id) {
         resultSet.add(A[i]);
         break;
      }
   }
}
return resultSet;

可以看出,当B表数据较大时不适合使用in(),因为它会B表数据全部遍历一次.
如:A表有10000条记录,B表有1000000条记录,那么最多有可能遍历10000*1000000次,效率很差.
再如:A表有10000条记录,B表有100条记录,那么最多有可能遍历10000*100次,遍历次数大大减少,效率大大提升.

结论:in()适合B表比A表数据小的情况

exist

select a.* from A a where exists(select 1 from B b where b.id=a.id)

以上查询使用了exists语句,exists()会执行A.length次,它并不缓存exists()结果集,因为exists()结果集的内容并不重要,重要的是结果集中是否有记录,如果有则返回true,没有则返回false.
它的查询过程类似于以下过程

List resultSet=[];
Array A=(select * from A)

for(int i=0;i<A.length;i++) {
   if(exists(A[i].id) {    //执行select 1 from B b where b.id=a.id是否有记录返回
       resultSet.add(A[i]);
   }
}
return resultSet;

当B表比A表数据大时适合使用exists(),因为它没有那么遍历操作,只需要再执行一次查询就行.
如:A表有10000条记录,B表有1000000条记录,那么exists()会执行10000次去判断A表中的id是否与B表中的id相等.
如:A表有10000条记录,B表有100000000条记录,那么exists()还是执行10000次,因为它只执行A.length次,可见B表数据越多,越适合exists()发挥效果.
再如:A表有10000条记录,B表有100条记录,那么exists()还是执行10000次,还不如使用in()遍历10000*100次,因为in()是在内存里遍历比较,而exists()需要查询数据库,我们都知道查询数据库所消耗的性能更高,而内存比较很快.

结论:exists()适合B表比A表数据大的情况

注意:select * from A where exist (select null),此时返回的全是true,查询出A的所有数据。

当A表数据与B表数据一样大时,in与exists效率差不多,可任选一个使用.

总之:设表A在外,表B在内

当B表记录较小时,用in

当A表记录较小时,用exist

IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。

 

 

UNION

 sql union all的执行效率要比sql union效率要高很多,这是因为,使用sql union需要进行排重,而sql union All 是不需要排重的,这一点非常重要,因为对于一些单纯地使用分表来提高效率的查询,完全可以使用sql union All

http://www.ibm.com/developerworks/cn/data/library/techarticles/dm-1002limh/index.html?ca=drs-tp4608

http://blog.csdn.net/lick4050312/article/details/4476333

http://www.vckbase.com/index.php/p/842(最全,最好)

 

转载于:https://www.cnblogs.com/hongdada/archive/2013/02/22/2921847.html