以前一直有个疑惑,例如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