[20190219]那个更快(11g).txt

--//前几天测试11g Query Result Cache RC Latches时,链接http://blog.itpub.net/267265/viewspace-2632907/
--//有网友指出测试有问题,建立索引唯一,并不会导致select count(*) from t,选择索引执行.实际上执行计划还是全表扫描.
--//也就有了如下测试,不过结果有点让我吃惊,设置not null反而更慢.通过测试说明:
--//另外我也做了10g下的测试,链接如下:http://blog.itpub.net/267265/viewspace-2636321/ => [20190215]那个更快(10g).txt

1.环境:
SCOTT@book> @ ver1
PORT_STRING                    VERSION        BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx            11.2.0.4.0     Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

create table t as select rownum id from dual ;
--//分析表略.
--//另外说明一下,先建立表主要避免编译过程时报错.

2.建立测试环境:
create table job_times (sid number, time_ela number,method varchar2(20));

CREATE OR REPLACE PROCEDURE do_work
(
   p_iterations   IN NUMBER
  ,p_method       IN VARCHAR2
)
IS
   l_rowid   ROWID;
   v_t       NUMBER;
BEGIN
   INSERT INTO job_times VALUES ( SYS_CONTEXT ('userenv', 'sid') ,DBMS_UTILITY.get_time ,p_method) RETURNING ROWID INTO l_rowid;

FOR i IN 1 .. p_iterations
   LOOP
      SELECT COUNT (*) INTO v_t FROM t;
   END LOOP;

UPDATE job_times SET time_ela = DBMS_UTILITY.get_time - time_ela WHERE ROWID = l_rowid;

COMMIT;
END;
/

CREATE OR REPLACE PROCEDURE do_work1
(
   p_iterations   IN NUMBER
  ,p_method       IN VARCHAR2
)
IS
   l_rowid   ROWID;
   v_t       NUMBER;
BEGIN
   INSERT INTO job_times VALUES ( SYS_CONTEXT ('userenv', 'sid') ,DBMS_UTILITY.get_time ,p_method) RETURNING ROWID INTO l_rowid;

FOR i IN 1 .. p_iterations
   LOOP
      SELECT COUNT (*) INTO v_t FROM t where id=1;
   END LOOP;

UPDATE job_times SET time_ela = DBMS_UTILITY.get_time - time_ela WHERE ROWID = l_rowid;

COMMIT;
END;
/

3.测试:
--//执行脚本如下:注一定要等N个会话执行完成在回车,进行下一项测试.
--//可以打开另外的会话执行select method,count(*),avg(TIME_ELA),sum(TIME_ELA) from job_times group by method order by 3 ;
--//确定测试是否完成.

$ cat bb.txt
delete from job_times;
commit ;
drop table t purge;
create table t as select rownum id from dual ;
execute sys.dbms_stats.gather_table_stats ( OwnName => user,TabName => 't',Estimate_Percent => NULL,Method_Opt => 'FOR ALL COLUMNS SIZE 1 ',Cascade => True ,No_Invalidate => false);
alter procedure do_work compile ;
alter procedure do_work1 compile ;
host sleep 5

host seq &&1 | xargs -I{} echo "sqlplus -s -l  scott/&&2 <<< \"execute do_work(&&3,'null')\" & "  | bash > /dev/null
host read -p 'wait finish...'

create unique index pk_t on t(id);
alter table t modify (id  not null);
host seq &&1 | xargs -I{} echo "sqlplus -s -l  scott/&&2 <<< \"execute do_work(&&3,'notnull')\" & "  | bash > /dev/null
host read -p 'wait finish...'

host seq &&1 | xargs -I{} echo "sqlplus -s -l  scott/&&2 <<< \"execute do_work1(&&3,'id=1_unique_index')\" & "  | bash > /dev/null
host read -p 'wait finish...'

drop index pk_t ;
create index pk_t on t(id);
host seq &&1 | xargs -I{} echo "sqlplus -s -l  scott/&&2 <<< \"execute do_work1(&&3,'id=1_index')\" & "  | bash > /dev/null
host read -p 'wait finish...'

alter table t result_cache (mode force);
host seq &&1| xargs -I{} echo "sqlplus -s -l  scott/&&2 <<< \"execute do_work(&&3,'result_cache')\" & "  | bash > /dev/null
host read -p 'wait finish...'

--//简单说明:执行需要3个参数,参数1:启动连接数,参数2:scott口令,参数3,循环次数.
--//执行如下:  @ bb.txt 50 book 1e6
--//第1种方式:执行计划是全表扫描,逻辑读2(10g下这里是3),看到的等待事件是cursor: pin S.很奇怪11g下看不到latch: cache buffers chains相关等待事件.
--//第2种方式:建立唯一索引,加入约束id not null,这样执行计划INDEX FULL SCAN,逻辑读1.看到的等待事件是latch: cache buffers chains,偶尔能看到cursor: pin S.
--//第3种方式:执行语句加入谓词id=1,这样执行计划INDEX UNIQUE SCAN,逻辑读1.看到的等待事件是cursor: pin S,在11g下latch: cache buffers chains看不到.
              注:在这种情况cbc latch减少一半比其它方式.
--//第4种方式:索引修改非唯一,执行语句加入谓词id=1,这样执行计划是INDEX RANGE SCAN,逻辑读1.看到的等待事件是latch: cache buffers chains.偶尔能看到cursor: pin S.
--//第5种方式:设置result_cache=force;逻辑读0,看到的等待事件是cursor: pin S.

--//测试结果如下:
SCOTT@book> select method,count(*),round(avg(TIME_ELA),0),sum(TIME_ELA) from job_times group by method order by 3 ;
METHOD                 COUNT(*) ROUND(AVG(TIME_ELA),0) SUM(TIME_ELA)
-------------------- ---------- ---------------------- -------------
result_cache                 50                   8611        430536
id=1_unique_index            50                   9494        474714
null                         50                  10664        533197
id=1_index                   50                  28160       1407987
notnull                      50                  29279       1463928

--//你可以发现结果按照快慢排序 result_cache => id=1_unique_index => null => id=1_index,notnull,实际上最后2个结果很接近.

--//使用result_cache 最快很好理解,为什么设置列NULL比not null快许多呢?

--//而且设置字段id NULL是全表扫描,至少2个逻辑读(对于ctas建立的表),而设置字段id NOT NULL 走的是快速全索引扫描(1个逻辑读).
--//看测试结果 not null的情况下几乎慢了3倍.

--//实际上字段设置 not null更慢.因为这时出现cursor: pin S 外,还出现外还大量出现 latch: cache buffers chains,而全表扫描
--//反而不出现latch: cache buffers chains等待事件.这样设置not null反而更慢.

--//11g在处理latch: cache buffers chains上做了一些优化,读读情况下有时候看不到cbc latch.
--//不过id=1_unique_index这样的情况下反而比10g执行要慢.
--//在10g下测试如下:
SCOTT@test> select method,count(*),round(avg(TIME_ELA),0),sum(TIME_ELA) from job_times group by method order by 3 ;
METHOD                 COUNT(*) ROUND(AVG(TIME_ELA),0) SUM(TIME_ELA)
-------------------- ---------- ---------------------- -------------
id=1_unique_index            50                   4864        243192
notnull                      50                  34134       1706713
id=1_index                   50                  34703       1735173
null                         50                  37234       1861717

--//实际上10g,11g是硬件配置一样,os安装也一样.
--//附上监测wait脚本:
 $ cat wait.sql
select p1raw,p2raw,p3raw,p1,p2,p3,sid,serial#,seq#,event,status,state,wait_time_micro,seconds_in_wait,wait_class
from v$session where ( wait_class<>'Idle' or (status='ACTIVE' and STATE='WAITED KNOWN TIME'))
and sid not in (select sid from v$mystat where rownum=1)
order by event ;

[20190219]那个更快(11g).txt的更多相关文章

  1. [20190423]那个更快的疑问3.txt

    [20190423]那个更快的疑问3.txt --//前一阵子,做了11g在单表单条记录唯一索引扫描的测试,摘要如下:--//参考链接:http://blog.itpub.net/267265/vie ...

  2. [20190401]那个更快的疑问.txt

    [20190401]那个更快的疑问.txt --//前一阵子,做了11g于10g下,单表单条记录唯一索引扫描的测试,摘要如下:--//参考链接:http://blog.itpub.net/267265 ...

  3. 让你的 Node.js 应用跑得更快的 10 个技巧(转)

    Node.js 受益于它的事件驱动和异步的特征,已经很快了.但是,在现代网络中只是快是不行的.如果你打算用 Node.js 开发你的下一个Web 应用的话,那么你就应该无所不用其极,让你的应用更快,异 ...

  4. 让你的 Node.js 应用跑得更快的 10 个技巧

    Node.js 受益于它的事件驱动和异步的特征,已经很快了.但是,在现代网络中只是快是不行的.如果你打算用 Node.js 开发你的下一个Web 应用的话,那么你就应该无所不用其极,让你的应用更快,异 ...

  5. Gradle更小、更快构建APP的奇淫技巧

    本文已获得原作者授权同意,翻译以及转载原文链接:Build your Android app Faster and Smaller than ever作者:Jirawatee译文链接:Gradle更小 ...

  6. linux 下程序员专用搜索源码用来替代grep的软件ack(后来发现一个更快的: ag), 且有vim插件的

    发现一个比ack更快更好用的:  https://github.com/ggreer/the_silver_searcher   , 使用时命令为ag,它是基于ack的代码二次开发的,所有使用方法基本 ...

  7. 使用QFileInfo类获取文件信息(在NTFS文件系统上,出于性能考虑,文件的所有权和权限检查在默认情况下是被禁用的,通过qt_ntfs_permission_lookup开启和操作。absolutePath()必须查询文件系统。而path()函数,可以直接作用于文件名本身,所以,path() 函数的运行会更快)

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/Amnes1a/article/details/65444966QFileInfo类为我们提供了系统无 ...

  8. 精通Web Analytics 2.0 (9) 第七章:失败更快:爆发测试与实验的能量

    精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第七章:失败更快:爆发测试与实验的能量 欢迎来到实验和测试这个棒极了的世界! 如果Web拥有一个超越所有其他渠道的巨大优势,它就 ...

  9. 假如 UNION ALL 里面的子句 有 JOIN ,那个执行更快呢

    比如: select id, name from table1 where name = 'x' union all select id, name from table2 where name =  ...

随机推荐

  1. Java-jsoup-解析HTML

    /**  * jsoup 是一款 Java 的HTML 解析器,可直接解析某个URL地址.HTML文本内容.它提供了一套非常省力的API,可通过DOM,CSS以及类似于JQuery的操作方法来取出和操 ...

  2. Hadoop学习笔记(二):简单操作

    1. 启动namenode和datanode,在master上输入命令hdsf dfsadmin -report查看整个集群的运行情况(记得关闭防火墙) 2. 输入命令查看hadoop监听的端口,ne ...

  3. MFC原理第三讲.RTTI运行时类型识别

    MFC原理第三讲.RTTI运行时类型识别 一丶什么是RTTI RTTI. 运行时的时候类型的识别. 运行时类型信息程序.能够使用基类(父类)指针 或者引用 来检查这些指针或者引用所指的对象. 实际派生 ...

  4. 进程间通信IPC-消息队列

    前言: 消息队列就是一个消息的链表.可以把消息看作一个记录,具有特定的格式以及特定的优先级.对消息队列有写权限的进程可以向其中按照一定的规则添加新消息:对消息队列有读权限的进程则可以从消息队列中读走消 ...

  5. 使用字面量,比new更加有效

    参考原文:http://www.cnblogs.com/yxf2011/archive/2012/04/01/2428225.html http://www.cnblogs.com/mushishi/ ...

  6. 【春华秋实】.NET Framework与.NET Core

    C#是微软发布的面向对象的,运行与.NET Framework之上的高级程序设计语言,属于编译型语言,也是目前.NET Framework的主角.C#语言语法简单而优雅,同时也有着很高的开发效率,尤其 ...

  7. 2016 ACM/ICPC亚洲区青岛站现场赛(部分题解)

    摘要 本文主要列举并求解了2016 ACM/ICPC亚洲区青岛站现场赛的部分真题,着重介绍了各个题目的解题思路,结合详细的AC代码,意在熟悉青岛赛区的出题策略,以备战2018青岛站现场赛. HDU 5 ...

  8. python布尔类型和逻辑运算

    布尔类型 python中True表示真,False表示假,它们是布尔类型: >>> type(True) <class 'bool'> 在python中,bool的Tru ...

  9. 35.QT-多线程

    程序和进程的区别 进程是动态的,程序是静态的,进程是程序运行时的实例,是占用系统运行资源的程序 进程是暂时的,程序是永久的, 进程是通过程序运行时得到的 程序是一个数据文件,进程是内存中动态的运行实体 ...

  10. Hibernate-在Eclipse(Oxygen)中安装Hibernatetools插件

    Eclipse(Luna)中是没有Hibernate插件的,该插件是需要自己进行添加. 在网上找了一下关于如何在Eclipse中安装Hibernatetools插件的方法,很多都是先找到Hiberna ...