sql 语句性能调优
数据库性能问题:非常低的并发,令人崩溃的响应时间,长时间的锁等待,锁升级 , 甚至是死锁,等等
“根据我们的经验(由很多业界专家证明),在 SQL Server 上取得的性能提高有 80% 来自对 SQL 编码的改进,而不是来自于对于配置或系统性能的调整。”
—凯文 克莱恩等,Transact-SQL Programming 作者
“经验表明 80%-90% 的性能调优是在应用级做的,而不是在数据库级”
—托马斯 白特,Expert One on One: Oracle
作者
1.根据权重来优化查询条件
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