[20170426]为什么是4秒.txt

[20170426]为什么是4秒.txt

--//在开发程序时我一般会强调开发尽量不要写一些自定义函数,往往可能导致CPU忙。今天测试遇到一个问题:
--//原始的测试来之nimishgarg.blogspot.com/2016/03/avoiding-unnecessary-function-calls-to.html

--//先重复测试。

1.环境:
SCOTT@book> @ &r/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

2.普通函数:
CREATE OR REPLACE FUNCTION get_dept (p_deptno dept.deptno%TYPE)
   RETURN dept.dname%TYPE
IS
   l_dname   dept.dname%TYPE;
BEGIN
   DBMS_LOCK.sleep (1);

   SELECT dname
     INTO l_dname
     FROM dept
    WHERE deptno = p_deptno;

   RETURN l_dname;
END;
/

SCOTT@book> select empno, ename, deptno, get_dept(deptno) c20 from emp;
     EMPNO ENAME          DEPTNO C20
---------- ---------- ---------- --------------------
      7369 SMITH              20 RESEARCH
      7499 ALLEN              30 SALES
      7521 WARD               30 SALES
      7566 JONES              20 RESEARCH
      7654 MARTIN             30 SALES
      7698 BLAKE              30 SALES
      7782 CLARK              10 ACCOUNTING
      7788 SCOTT              20 RESEARCH
      7839 KING               10 ACCOUNTING
      7844 TURNER             30 SALES
      7876 ADAMS              20 RESEARCH
      7900 JAMES              30 SALES
      7902 FORD               20 RESEARCH
      7934 MILLER             10 ACCOUNTING
14 rows selected.
Elapsed: 00:00:14.02

--//这样每一次调用都需要1秒。如果改用标量子查询。

SCOTT@book> select empno, ename, deptno, (select get_dept(deptno) from dual )c20 from emp;
     EMPNO ENAME          DEPTNO C20
---------- ---------- ---------- --------------------
      7369 SMITH              20 RESEARCH
      7499 ALLEN              30 SALES
      7521 WARD               30 SALES
      7566 JONES              20 RESEARCH
      7654 MARTIN             30 SALES
      7698 BLAKE              30 SALES
      7782 CLARK              10 ACCOUNTING
      7788 SCOTT              20 RESEARCH
      7839 KING               10 ACCOUNTING
      7844 TURNER             30 SALES
      7876 ADAMS              20 RESEARCH
      7900 JAMES              30 SALES
      7902 FORD               20 RESEARCH
      7934 MILLER             10 ACCOUNTING
14 rows selected.
Elapsed: 00:00:03.01

--//因为标量子查询,缓存了相同的结果,deptno仅仅有3个值,这样需要3秒。自己还真没想到标量子查询有这样效果!!

3. DETERMINISTIC Functions:

--//一般如果在在某个函数定义索引,需要DETERMINISTIC,表示返回结果固定。其实即使不固定,也可以这样定义。
CREATE OR REPLACE FUNCTION get_dept (p_deptno dept.deptno%TYPE)
   RETURN dept.dname%TYPE
   DETERMINISTIC
IS
   l_dname   dept.dname%TYPE;
BEGIN
   DBMS_LOCK.sleep (1);

   SELECT dname
     INTO l_dname
     FROM dept
    WHERE deptno = p_deptno;

   RETURN l_dname;
END;
/

SCOTT@book> select empno, ename, deptno, get_dept(deptno) c20 from emp;
     EMPNO ENAME          DEPTNO C20
---------- ---------- ---------- --------------------
      7369 SMITH              20 RESEARCH
      7499 ALLEN              30 SALES
      7521 WARD               30 SALES
      7566 JONES              20 RESEARCH
      7654 MARTIN             30 SALES
      7698 BLAKE              30 SALES
      7782 CLARK              10 ACCOUNTING
      7788 SCOTT              20 RESEARCH
      7839 KING               10 ACCOUNTING
      7844 TURNER             30 SALES
      7876 ADAMS              20 RESEARCH
      7900 JAMES              30 SALES
      7902 FORD               20 RESEARCH
      7934 MILLER             10 ACCOUNTING
14 rows selected.
Elapsed: 00:00:04.02

--//4秒,为什么呢?仅仅3个值,按照道理应该3秒,而不是4秒,这个问题先放在后面解析。

4.RESULT CACHE
CREATE OR REPLACE FUNCTION get_dept (p_deptno dept.deptno%TYPE)
   RETURN dept.dname%TYPE
   RESULT_CACHE
IS
   l_dname   dept.dname%TYPE;
BEGIN
   DBMS_LOCK.sleep (1);

   SELECT dname
     INTO l_dname
     FROM dept
    WHERE deptno = p_deptno;

   RETURN l_dname;
END;
/

SCOTT@book> select empno, ename, deptno, get_dept(deptno) c20 from emp;
..
14 rows selected.
Elapsed: 00:00:03.01

--//再次执行因为结果缓存了。很快返回。

SCOTT@book> select empno, ename, deptno, get_dept(deptno) dname from emp;
14 rows selected.
Elapsed: 00:00:00.00

5.回到前面,采用 DETERMINISTIC Functions为什么是4秒呢?

--//重新定义函数
CREATE OR REPLACE FUNCTION get_dept (p_deptno dept.deptno%TYPE)
   RETURN dept.dname%TYPE
   DETERMINISTIC
IS
   l_dname   dept.dname%TYPE;
BEGIN
   DBMS_LOCK.sleep (1);

   SELECT dname
     INTO l_dname
     FROM dept
    WHERE deptno = p_deptno;

   RETURN l_dname;
END;
/

--//如果仔细阅读原文:
As we can see here that execution time went down to near 4 seconds which was originally near 14 seconds. We can notice
that using scalar sub-query was little faster because Deterministic cache is maintained per fetch instead of total SQL
execution. I prefer to modify my function to deterministic only when I know that this function is used in various SQLs
and all SQL can not be modified (or required alot of effort) with scalar sub-query.

SCOTT@book> show array
arraysize 200
--//仔细看就明白了,实际与array大小有关,这样就很容易理解为什么是4秒,因为返回第1行是单独1个逻辑读。

--如果我设置array=2
20          1
30 30       1
20 30       2
30 10       2
20 10       2
30 20       2
30 20       2
10          1
--//这样13秒验证是否正确。

SCOTT@book> set array 2
SCOTT@book> select empno, ename, deptno, get_dept(deptno) c20 from emp;
14 rows selected.
Elapsed: 00:00:13.02

--//如果我设置array=3
20           1
30 30 20     2
30 30 10     2
20 10 30     3
20 30 20     2
10           1
--//这样11秒验证是否正确。
SCOTT@book> set array 3
SCOTT@book> select empno, ename, deptno, get_dept(deptno) c20 from emp;
...
14 rows selected.
Elapsed: 00:00:11.02

--//如果我设置array=4
set array 4
20              1
30 30 20 30     2
30 10 20 10     3
30 20 30 20     2
10              1
--//应该是9秒:
SCOTT@book> select empno, ename, deptno, get_dept(deptno) c20 from emp ;
14 rows selected.
Elapsed: 00:00:09.01

--//如果你仔细观察输出时的停顿,可以发现是4条4条输出的,这里非常不好理解!!
--//但是如果改用标量子查询,结果就是3秒。

SCOTT@book> select empno, ename, deptno, (select get_dept(deptno) from dual )c20 from emp;
14 rows selected.
Elapsed: 00:00:03.01

--//还有1个简单的验证方法就是排序输出看看。
SCOTT@book> select empno, ename, deptno, get_dept(deptno) c20 from emp order by deptno;
14 rows selected.
Elapsed: 00:00:03.01

--//这样数据先进入排序区,arraysize大小就变得没有关系,有回到3秒。
--//其中细节可以自己体会。

--//这个测试终于让我明白oracle一些逻辑读细节。

总结
1.oracle 逻辑读不能跨块。
2.oracle 逻辑读第1行作为一个逻辑读,接着读取数量array作为第2个逻辑读。
3.做一个特殊情况:
SCOTT@book> create table empx as select * from emp order by deptno;
Table created.

SCOTT@book> select * from empx ;
     EMPNO ENAME      JOB              MGR HIREDATE                   SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
      7782 CLARK      MANAGER         7839 1981-06-09 00:00:00       2450                    10
      7839 KING       PRESIDENT            1981-11-17 00:00:00       5000                    10
      7934 MILLER     CLERK           7782 1982-01-23 00:00:00       1300                    10
      7566 JONES      MANAGER         7839 1981-04-02 00:00:00       2975                    20
      7902 FORD       ANALYST         7566 1981-12-03 00:00:00       3000                    20
      7876 ADAMS      CLERK           7788 1987-05-23 00:00:00       1100                    20
      7369 SMITH      CLERK           7902 1980-12-17 00:00:00        800                    20
      7788 SCOTT      ANALYST         7566 1987-04-19 00:00:00       3000                    20
      7521 WARD       SALESMAN        7698 1981-02-22 00:00:00       1250        500         30
      7844 TURNER     SALESMAN        7698 1981-09-08 00:00:00       1500          0         30
      7499 ALLEN      SALESMAN        7698 1981-02-20 00:00:00       1600        300         30
      7900 JAMES      CLERK           7698 1981-12-03 00:00:00        950                    30
      7698 BLAKE      MANAGER         7839 1981-05-01 00:00:00       2850                    30
      7654 MARTIN     SALESMAN        7698 1981-09-28 00:00:00       1250       1400         30
14 rows selected.

SCOTT@book> set array 7
SCOTT@book> select empno, ename, deptno, get_dept(deptno) c20 from empx ;
     EMPNO ENAME          DEPTNO C20
---------- ---------- ---------- --------------------
      7782 CLARK              10 ACCOUNTING
      7839 KING               10 ACCOUNTING
      7934 MILLER             10 ACCOUNTING
      7566 JONES              20 RESEARCH
      7902 FORD               20 RESEARCH
      7876 ADAMS              20 RESEARCH
      7369 SMITH              20 RESEARCH
      7788 SCOTT              20 RESEARCH
      7521 WARD               30 SALES
      7844 TURNER             30 SALES
      7499 ALLEN              30 SALES
      7900 JAMES              30 SALES
      7698 BLAKE              30 SALES
      7654 MARTIN             30 SALES
14 rows selected.
Elapsed: 00:00:04.02

10                    1
10 10 20 20 20 20 20  2
30 30 30 30 30 30     1

--//如果设置6,多2秒。
SCOTT@book> set array 6
SCOTT@book> select empno, ename, deptno, get_dept(deptno) c20 from empx ;
     EMPNO ENAME          DEPTNO C20
---------- ---------- ---------- --------------------
      7782 CLARK              10 ACCOUNTING
      7839 KING               10 ACCOUNTING
      7934 MILLER             10 ACCOUNTING
      7566 JONES              20 RESEARCH
      7902 FORD               20 RESEARCH
      7876 ADAMS              20 RESEARCH
      7369 SMITH              20 RESEARCH
      7788 SCOTT              20 RESEARCH
      7521 WARD               30 SALES
      7844 TURNER             30 SALES
      7499 ALLEN              30 SALES
      7900 JAMES              30 SALES
      7698 BLAKE              30 SALES
      7654 MARTIN             30 SALES
14 rows selected.
Elapsed: 00:00:06.01

10                    1
10 10 20 20 20 20     2
20 30 30 30 30 30     2
30                    1

--//OK正确。

4.不过我自己还是有一点不明白的,oracle的输出是按照array定义的数量输出的,不知道为什么?
  按照我的理解输出应该是1,array数量-1,array数量...,有谁能给出合理解析呢?

时间: 2024-07-30 10:54:12

[20170426]为什么是4秒.txt的相关文章

[20170909]为什么是12秒.txt

[20170909]为什么是12秒.txt --//在开发程序时我一般会强调开发尽量不要写一些自定义函数,往往可能导致CPU忙. --//例子很像这样: CREATE OR REPLACE FUNCTION get_dept (p_deptno dept.deptno%TYPE)    RETURN dept.dname%TYPE IS    l_dname   dept.dname%TYPE; BEGIN    DBMS_LOCK.sleep (1);    SELECT dname     

[20170426]漫长的测试时间.txt

[20170426]漫长的测试时间.txt --//昨天浏览一个blog,链接nimishgarg.blogspot.com/2015/11/plsql-tuning-bind-variables-and-execute.html --//里面提到主要是绑定变量的问题,让我感到奇怪的是对方的测试时间:Elapsed: 00:27:15.55(在不使用绑定变量的情况下). --//这个时间也太长了,我以前也做过了类似测试执行2万次sql语句大约10秒上下,这样对于他建立的测试例子最多在1分钟之内.

php守护进程 加linux命令nohup实现任务每秒执行一次

Unix中 nohup 命令功能就是不挂断地运行命令,同时 nohup 把程序的所有输出到放到当前目录 nohup.out 文件中,如果文件不可写,则放到 <用户主目录>/nohup.out 文件中.那么有了这个命令以后我们php就写成shell 脚本使用循环来让我们脚本一直运行下去,不管我们终端窗口是否关闭都能够让我们php 脚本一直运行下去. 马上动手写个 PHP 小程序,功能为每30秒记录时间,写入到文件 复制代码 代码如下: # vi for_ever.php #! /usr/loca

解密SEO:低权重网站如何挑战“秒收”梦境

在传统的SEO优化认可中,网站收录速度越快便表示其权重越高,因为收录速度决定了搜索引擎的关注度.然而时至今日,秒收不再是高权重网站的特权,通过合理优化,新站依旧可以挑战秒收特权.而虽无权重,但在不断的快速收录下,却可快速提升网站排名,且利用这个优势更可换到高质量的友情链接加速网站发展.因为对一个可以秒收的网站站来说,其网站优化水准以及内容的质量都是较为优秀的,由此才可以达到秒收的效果.那么,新站如何以低权重来挑战秒收梦境呢?本文做出以下理解: 一:网站定位与发展核心要紧密 网站质量的好坏从发展核

秒收首页18天内收录内页日记

首先我们会拿案例:不锈钢带这个网站来做具体操作实例 第一.用户分析篇 在做一个网站的时候首先要观察和统计用户需求才可以做一个好的站点对用户有用的站点,首先要了解这个行业或者这个关键词的用户需求是什么,用户点击趋向什么,一定要做到附加价值的提升,当你抓住用户的需求,那么给他提高附加价值那么你就抓住了用户流量做到了"流行酷". 1.统计行业关键词以及相关长尾词.分析关键词用户的点击搜索趋向 根据案例:不锈钢带 首先.我们根据搜索引擎给我们的一些个条件 百度下不锈钢带下拉词条会出现   这个

分享权重低的网站让蜘蛛秒收的经验

  大家在页面收录都有共识,那就是网站权重越高收录就越快,由于权重高的网站受到搜索引擎的关注度高.然而权重低的网站照样可以得到搜索引擎的关注,只要通过合理的网站优化,照样可以得到搜索引擎的秒收,反之快速收录也可以提升网站的权重,下面 我来分享一下我的网站如何被秒收. 一. 网站的定向 有一些网站在建站或是在优化过程没有定位好网站的发展方向,导致网站的内容杂乱无序,没有频道之分,这样内容杂乱地更新网站还不如不要更新,会给蜘蛛留下不专业的感觉.如果要发展一个网站必需反复强调与优化同一个主题,长期下来

如何将pdf格式转换成txt格式的详细图文教程

常在网上找一些资料,但是通常很多好的资料都为pdf格式的文件.对于一个电脑小白来说,pdf格式的文件也许会很陌生,第一个面临的就是pdf格式的文件怎么打开?顺便解答一下:pdf格式的文件必须用相应的pdf阅读器才能打开哦.好了,及时收住话题,因为PC6小编今天要教大家的是如何把pdf格式的文件转换为txt文本,因为我们发现,现在一般的pdf阅读器打开pdf文件后并不支持复制pdf文件的内容,这个时候我们我们就只有转换格式来达到目的了! 今天给大家推荐的一款工具是汉王PDF OCR,汉王 PDF

txt文档和bat批处理文件妙用

  你是否有曾经想象过自己成为一名IT精英,畅游代码的海洋,每天解读着别人所不能理解的世界,从代码中参悟真理看透一切真相,这会是一种什么滋味呢?也许你会说,我没学过代码,也当不成程序员,如何感受的到?其实如果仅仅是想体会一下编写程序代码实现某种自动化处理的快乐并不需要高深的理论知识和旷日持久的学习,txt这个平日里最常见的临时文档文件就能够帮助你,用它易于转化为bat批处理文件的特性足以让你发挥想象力,创造出属于自己的代码实现自己专属的小程序. 其实批处理文件的历史相当长,它在DOS时代就已经存

怎么将pdf格式文件转换成txt格式

  常在网上找一些资料,但是通常很多好的资料都为pdf格式的文件.对于一个电脑小白来说,pdf格式的文件也许会很陌生,第一个面临的就是pdf格式的文件怎么打开?顺便解答一下:pdf格式的文件必须用相应的pdf阅读器才能打开哦.因为我们发现,现在一般的pdf阅读器打开pdf文件后并不支持复制pdf文件的内容,这个时候我们我们就只有转换格式来达到目的了! 下面给大家推荐的一款工具是汉王PDF OCR,汉王 PDF OCR 提供 PDF 自动转换 RTF/TXT 功能,同时支持TIFF/JPEG/GI