关于rownum的一个小实验

以前一直有个疑惑,例如sql:select * from test where object_name=‘YANG‘ and rownum=1;
那么该sql是把所有的object_name=‘YANG‘全部都找出来显示一行给我呢,还是只找到一行了就停止再找?
话不多说,做个小实验:

1.构造一张表
create table test as select * from dba_objects;

2.将表的第一行作个更改
update test set object_name=‘YANG‘ where object_id=20;
commit;

3.查询object_name=‘YANG‘的总行数
select count(*) from test where object_name=‘YANG‘;
这个就不贴了,肯定是1行

4.查看该sql的执行计划和统计信息
set autot trace exp stat
select * from test where object_name=‘YANG‘ and rownum=1;
(注意将以上sql多执行几次,让统计信息准确)

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     1 |   207 |    36   (0)| 00:00:01 |
|*  1 |  COUNT STOPKEY     |      |       |       |            |          |
|*  2 |   TABLE ACCESS FULL| TEST |    20 |  4140 |    36   (0)| 00:00:01 |
---------------------------------------------------------------------------

1 - filter(ROWNUM=1)
   2 - filter("OBJECT_NAME"=‘YANG‘)

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          4  consistent gets
          0  physical reads
          0  redo size
       1604  bytes sent via SQL*Net to client
        523  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed
发现只有四个逻辑读

5.将表的最后一行作个更改(表的第一行和最后一行可以根据rowid进行选择)
update test set object_name=‘YANG‘ where object_id=88611;
commit;

6.查询object_name=‘YANG‘的总行数
select count(*) from test where object_name=‘YANG‘;
这个就不贴了,肯定是2行

7.将以下sql执行一次,查看该sql的执行计划和统计信息
select * from test where object_name=‘YANG‘ and rownum=1;
发现跟第4步没什么区别,逻辑读都为4。那也就是说这次虽说有两行object_name=‘YANG‘,而且处于表的一头一尾,但是数据库只扫描到第一个满足条件的就退出了,所以说rownum=1的话,数据库只找到一行了就停止再找。

8.继续验证自己的结论
select * from test where object_name=‘YANG‘ and rownum<3;
---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     2 |   414 |    53   (0)| 00:00:01 |
|*  1 |  COUNT STOPKEY     |      |       |       |            |          |
|*  2 |   TABLE ACCESS FULL| TEST |    20 |  4140 |    53   (0)| 00:00:01 |
---------------------------------------------------------------------------

1 - filter(ROWNUM<3)
   2 - filter("OBJECT_NAME"=‘YANG‘)

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       1248  consistent gets
          0  physical reads
          0  redo size
       1729  bytes sent via SQL*Net to client
        523  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          2  rows processed
可以看到该sql为了找到2行,对表进行了个全扫描,对应的逻辑读也到了1248个,所以此刻更加肯定了在第七步中的结论。

后记:有些时候,我们都会被一些很莫名其妙的思路困扰,别担心,做个小实验就行了。

原文地址:https://www.cnblogs.com/ddzj01/p/9028217.html

时间: 2024-10-10 01:57:37

关于rownum的一个小实验的相关文章

关于purge master logs的一个小实验

原理部分来自<MariaDB原理与实现> Page109-111 purge删除binlog的过程如下: 1.检查to_log在mysql-bin.index中是否存在,避免非法的purge操作 2.创建一个purge_index_file,用于保存待删除的binlog文件名称 3.遍历index文件,将可删除的binlog添加到purge_index_file中(purge删除时候,只会把未使用到的binlog之前的文件删除掉) 4.将purge_index_file的内容写入到磁盘 5.更

json小实验

看了汤姆大叔的博客http://www.cnblogs.com/TomXu/archive/2012/01/11/2311956.html 博客原文: 我认为很多JavaScript开发人员都错误地把JavaScript对象字面量(Object Literals)称为JSON对象(JSON Objects),因为他的语法和JSON规范里描述的一样,但是该规范里也明确地说了JSON只是一个数据交换语言,只有我们将之用在string上下文的时候它才叫JSON. // 这是JSON字符串 var fo

一个电磁感应小实验

手头有一个坏的音响,测试放大电路没有什么问题,所以变改造了一下.做了一个电磁感应的小实验.图片如下:    原理简介: 音响本身就是一个信号放大器,所以这里我用电脑声卡输出正弦信号,经过放大到线圈输出.电磁感应,另外一个线圈便会产生电压,可以驱动一个发光二极管. 这里是 matlab 产生正弦声波的程序(来自网络): 1 Fs = 44100;%采样频率 2 T = 4; %时间长度 3 n = Fs*T;%采样点数 4 f = 40000;%声音频率 5 y = sin(2*pi*f*T*li

DCDC纹波小实验

关于使用示波器测试纹波的注意事项 使用示波器的AC耦合方式测量 由于示波器的头套容易引人噪声,因此在测试前必需把探头的头套去掉 因为电源的高频噪声很容易通过小电感就可以滤掉,因此更关心的是中低频的噪声.测试时将示波器的带宽限制调到尽可能的低(20MHz),避免从表笔引入噪声(我之前就吃过这方面的亏) DCDC后端接LDO AMS1117-5V的Datasheet上要求的最低压差(VIN-VOUT)为1.1V到1.25V,这就要求输入要大于5V+1.1V=6.1V,如果输入不满足这个条件会怎么样呢

留言本小实验

实验目的: 利用PHP实现发布留言,并存在txt文本文件中,还可以从文本文件中读取留言,并显示在网页上. 实验代码: 先要用个表单提交留言,写一个简单的html如下: 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 2 <html xmlns="http://www

ES6小实验-let和const(2)

继续小实验,上次写到块级作用域,那么为什么需要块级作用域呢?书中给了两个场景: 1.没有块级作用域,内层变量可能会覆盖外层变量.举例: var tmp = new Date() function f() { console.log(tmp) if(false) { var tmp = "hello world" } } f();//undefined 内层的tmp变量把外层的tmp变量覆盖,所以输出结果为undefined 2.用来计数的循环变量泄露为全局变量,举例: var s =

关于用addr2line解析函数地址的一个小探索

最近知道用dmesg和addr2line配合能定位出段错误的具体行.于是自己做了个小实验,在试验中发现,这个办法有时候也是不灵光的,具体取决于段错误的类型. 我写的小程序: 编译之后运行出现段错误,先用dmesg命令找到出错的地址,再用addr2line定位行数,发现定位失败了.看来这种段错误用这种方法是不可行的. 以下是从网上找到的内容: Addr2line 工具(它是标准的 GNU Binutils 中的一部分)是一个可以将指令的地址和可执行映像转换成文件名.函数名和源代码行数的工具. dm

一个小程序的python和bash版本比较

最近有一个小需求:在一个目录下有很多文件,每个文件的第一行是BEGIN开头的,最后一行是END开头的,中间每一行有多列,数量不等,第一列称为"DN", 第二列称为"CV",DN和CV的联合作为主键,现在需要检测文件中是否有重复的DN-CV. 于是写了个简单的python程序 #! /usr/bin/python import os import sys cmd = "cat /home/zhangj/hosts/* | grep -v BEGIN | gr

开大Stack的一个小技巧

在程序头部添加一行 #pragma comment(linker, "/STACK:16777216") 可有效开大堆栈 实验效果如下: 11330179 2014-08-05 18:28:17 Wrong Answer 4920 1687MS 7776K 1327 B C++ Jeremy_wu 11272238 2014-07-31 19:50:26 Wrong Answer 4891 62MS 2368K 1402 B G++ Jeremy_wu 下面是没添加这一行的运行结果 上