最近在看梁敬彬老师关于Oracle性能优化的一些案例,在这里做一些简单的总结

1.COUNT(*)与COUNT(列)哪个更快

drop table t purge;

create table t as select * from dba_objects;

--alter table T modify object_id  null;

update t set object_id =rownum ;

set timing on 

set linesize 1000

set autotrace on 



select count(*) from t;

/

select count(object_id) from t;

推论1:在不建索引的情况下,count(*)和count(列)没有区别

看来count(列)比count(*) 更快是谣传,明明是一样快嘛,真相是这样吗?



建索引试试

create index idx_object_id on t(object_id);

select count(*) from t;



select count(object_id) from t;



推论2:原来真的是用COUNT(列)比COUNT(*)要快啊,因为COUNT(*)不能用到索引,而COUNT(列)可以,真相真是如此吗?



继续



alter table T modify object_id  not  null;

select count(*) from t;

select count(object_id) from t;

推论3:看来count(列)和count(*)其实一样快,如果索引列是非空的,count(*)可用到索引,此时一样快!真相真是如此吗?

其实两者根本没有可比性,性能比较首先要考虑写法等价,这两个语句根本就不等价!

最佳字段顺序(结论:越往后的列访问CPU开销大)



验证脚本1 (先构造出表和数据)

SET SERVEROUTPUT ON

SET ECHO ON

---构造出有25个字段的表T

DROP TABLE t;

DECLARE

  l_sql VARCHAR2(32767);

BEGIN

  l_sql := 'CREATE TABLE t (';

  FOR i IN 1..25 

  LOOP

    l_sql := l_sql || 'n' || i || ' NUMBER,';

  END LOOP;

  l_sql := l_sql || 'pad VARCHAR2(1000)) PCTFREE 10';

  EXECUTE IMMEDIATE l_sql;

END;

/

----将记录还有这个表T中填充

DECLARE

  l_sql VARCHAR2(32767);

BEGIN

  l_sql := 'INSERT INTO t SELECT ';

  FOR i IN 1..25

  LOOP

    l_sql := l_sql || '0,';

  END LOOP;

  l_sql := l_sql || 'NULL FROM dual CONNECT BY level <= 10000';

  EXECUTE IMMEDIATE l_sql;

  COMMIT;

END;

/



--验证脚本2(一次访问该表各字段验证) 

execute dbms_stats.gather_table_stats(ownname=>user, tabname=>'t')

SELECT num_rows, blocks FROM user_tables WHERE table_name = 'T';

--以下动作观察执行速度,比较发现COUNT(*)最快,COUNT(最大列)最慢

DECLARE

  l_dummy PLS_INTEGER;

  l_start PLS_INTEGER;

  l_stop PLS_INTEGER;

  l_sql VARCHAR2(100);

BEGIN

  l_start := dbms_utility.get_time;

  FOR j IN 1..1000

  LOOP

    EXECUTE IMMEDIATE 'SELECT count(*) FROM t' INTO l_dummy;

  END LOOP;

  l_stop := dbms_utility.get_time;

  dbms_output.put_line((l_stop-l_start)/100);





  FOR i IN 1..25

  LOOP

    l_sql := 'SELECT count(n' || i || ') FROM t';

    l_start := dbms_utility.get_time;

    FOR j IN 1..1000

    LOOP

      EXECUTE IMMEDIATE l_sql INTO l_dummy;

    END LOOP;

    l_stop := dbms_utility.get_time;

    dbms_output.put_line((l_stop-l_start)/100);

  END LOOP;

END;

/



结论:

原来优化器是这么搞的:列的偏移量决定性能,列越靠后,访问的开销越大。由于count(*)的算法与列偏移量无关,所以count(*)最快。

后面还有看图说话,看看结果输出的趋势图,就更了然了。

2.IN和EXISTS之争

10g执行一下

select * from v$version;

drop table emp purge;

drop table dept purge;

create table emp as select * from scott.emp;

create table dept as select * from scott.dept;

set timing on 

set linesize 1000

set autotrace traceonly 

select * from dept where deptno NOT IN ( select deptno from emp ) ;

select * from dept where not exists ( select deptno from emp where emp.deptno=dept.deptno) ;



select * from dept where deptno NOT IN ( select deptno from emp where deptno is not null) and deptno is not null;

-结论:10g与空值有关,如果确保非空,可以用到anti的半连接算法

11g执行一下

select * from v$version;



drop table emp purge;

drop table dept purge;

create table emp as select * from scott.emp;

create table dept as select * from scott.dept;

set timing on 

set linesize 1000

set autotrace traceonly explain

select * from dept where deptno NOT IN ( select deptno from emp ) ;

select * from dept where not exists ( select deptno from emp where emp.deptno=dept.deptno) ;



select * from dept where deptno NOT IN ( select deptno from emp where deptno is not null) and deptno is not null;



结论:11g与空值有关,都可以用到anti的半连接算法,执行计划一样,性能一样

版权声明:本文为博主原创文章,未经博主允许不得转载。

Oracle性能优化1-总体思路和误区的更多相关文章

  1. 【转载】我眼中的Oracle性能优化

    我眼中的Oracle性能优化 大家对于一个业务系统的运行关心有如下几个方面:功能性.稳定性.效率.安全性.而一个系统的性能有包含了网络性能.应用性能.中间件性能.数据库性能等等. 今天从数据库性能的角 ...

  2. 降低磁盘IO使Oracle性能优化(转)

    文章转自:http://blog.chinaunix.net/uid-26813519-id-3207996.html 硬件方面虽然只占Oracle性能优化的一个方面(另一方面是软件),但是仍不可忽视 ...

  3. 我眼中的 Oracle 性能优化

    恒生技术之眼 作者 林景忠 大家对于一个业务系统的运行关心有如下几个方面:功能性.稳定性.效率.安全性.而一个系统的性能有包含了网络性能.应用性能.中间件性能.数据库性能等等. 今天从数据库性能的角度 ...

  4. oracle性能优化之awr分析

    oracle性能优化之awr分析 作者:bingjava 最近某证券公司系统在业务期间系统运行缓慢,初步排查怀疑是数据库存在性能问题,因此导出了oracle的awr报告进行分析,在此进行记录. 导致系 ...

  5. Oracle 性能优化的基本方法

    Oracle 性能优化的基本方法概述 1)设立合理的性能优化目标. 2)测量并记录当前性能. 3)确定当前Oracle性能瓶颈(Oracle等待什么.哪些SQL语句是该等待事件的成分). 4)把等待事 ...

  6. Oracle性能优化小结

    Oracle性能优化小结 原则一.注意where子句中的连接顺序 Oracle采用自下而上的顺序解析where子句,根据这个原理,表之间的连接必须卸载其他where条件之前,哪些可以滤掉最大数量记录的 ...

  7. Oracle性能优化之SQL语句

    1.SQL语句执行过程 1.1 SQL语句的执行步骤 1)语法分析,分析语句的语法是否符合规范,衡量语句中各表达式的意义. 2)语义分析,检查语句中涉及的所有数据库对象是否存在,且用户有相应的权限. ...

  8. ORACLE性能优化之SQL语句优化

    版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[+]   操作环境:AIX +11g+PLSQL 包含以下内容: 1.  SQL语句执行过程 2.  优化器及执行计划 3.  合 ...

  9. Web性能优化:基本思路和常用工具

    听了荣华的演讲之后,我对性能优化有了更深层次的认识. 性能优化的重要性 性能优化是为了赢得用户,为了降低成本. 性能优化思路 Web常见优化点   Java常见排查工具  

随机推荐

  1. delphi 实现两个exe文件共享内存映像的代码

    创建内存映像的程序 ------------------------------------------------------------------------------------------ ...

  2. Cache雪崩效应

    大概半年前,Guang.com曾发生一次由于首页部分cache失效,导致网站故障. 故障分析: 当时逛正在做推广,流量突然暴增,QPS达到5000+,当首页部分cache失效时,需要查询DB, 但由于 ...

  3. 网络层——IP报文头介绍

    IP数据包也叫IP报文分组,传输在ISO网络7层结构中的网络层,它由IP报文头和IP报文用户数据组成,IP报文头的长度一般在20到60个字节之间,而一个IP分组的最大长度则不能超过65535个字节.  ...

  4. easyui中的几个问题

    easyui中的tree,采用url参数读取json,无法显示.有可能是vs的IIS不支持,$.ajax 原因待测试,有知道的朋友也可以贴代码,我解决的一个办法是 $(function () { $. ...

  5. C++ 自定义控件的移植(将在其它程序中设计的自定义控件,移植到现在的系统中)

    方法很简单就是将需要的代码 复制到 新系统中就可以了,方法就是 把相关文件添加到现有的系统中,并特别注意以下问题 \如果原设计中用到了菜单或是其它资源,相应的资源要在新的菜单中,手动添加. 目前没有发 ...

  6. JAVA语言 第四周

    oh my god! 说实话,上周的目标没有完成. 这一周过的太随便了,比刚放假时候的热情减少的太多了. 具体干了啥,就不说了吧.好像什么完整的事都没有干~~~~~ 不过一直在完善代码,已经能实现部分 ...

  7. 几个api看看

    require  nonull  inline  noinline crossinline

  8. hibernateTemplate API

    https://docs.spring.io/spring-framework/docs/2.5.x/api/org/springframework/orm/hibernate3/HibernateT ...

  9. mysql里max_allowed_packet的作用

    MySQL根据配置文件会限制Server接受的数据包大小.有时候大的插入和更新会受 max_allowed_packet 参数限制,导致写入或者更新失败. 查看目前配置: 代码如下: show VAR ...

  10. CRTD模拟MFG工单进行绑定优化

    需求:按单按库生产的CRTD状态半成品工单重复创建问题 绑定成功案例: SELECT DEMANDLINEID,SUPPLYORDERID,DEMANDORDERID,QTYALLOCATED,ITE ...