从Count看Oracle执行计划的选择
一、 前言
在调查一个性能问题的时候,一个同事问道,为什么数据库有些时候这么不聪明,明明表上有索引,但是在执行一个简单的count的时候居然全表扫描了!难道不知道走索引更快么?
试图从最简单的count来重新了解oracle查询计划的选择,以及最终产生的结果。虽然有些结果会让人觉得有些意外,并且可能会鄙视,这个查询计划选择真的不够聪明。但稍微用心点的去了解,做的已经足够细致了。大多数情况下,根据我们输入的信息,来自输入的SQL、表结构、索引状况、统计信息,会得出一个比较优的计划。所以和前面一直试图讲到索引和join方式一样,所有这样的选择不是因为数据库厂商这样规定的,而是基于存储的数据的实际情况,就**应该(甚至说不得不)**这么去选择。
1-- Create table
2create table IDOUBA.APP_APPLICATIONAUDIT
3(
4 ID NUMBER,
5 UNIQUEID NUMBER,
6 POLICYID NUMBER,
7 IP VARCHAR2(200) not null,
8 IPNUM NUMBER not null,
9 MAC VARCHAR2(200),
10 USERVISIT VARCHAR2(100),
11 PHONE VARCHAR2(200),
12 GROUPNAME VARCHAR2(100),
13 PORT NUMBER,
14 APP_URL VARCHAR2(200),
15 TITLE VARCHAR2(200),
16 REQUESTS VARCHAR2(1000),
17 REQIDENTITYCARD VARCHAR2(1000),
18 REQKEY VARCHAR2(1000),
19 RESPONSEEKEY VARCHAR2(3000),
20 UPDATETIME DATE,
21 AUDITTYPE NUMBER,
22 TITLEID NUMBER,
23 SUBTITLEID NUMBER,
24 SERVERIP VARCHAR2(200),
25 DOMAINNAME VARCHAR2(200)
26)
27tablespace USERS
28 pctfree 10
29 initrans 1
30 maxtrans 255
31 storage
32 (
33 initial 64K
34 minextents 1
35 maxextents unlimited
36 );
37-- Create/Recreate indexes
38create index INDEX_UPDATETIME on IDOUBA.APP_APPLICATIONAUDIT (UPDATETIME)
39 tablespace SYSTEM
40 pctfree 10
41 initrans 2
42 maxtrans 255
43 storage
44 (
45 initial 64K
46 minextents 1
47 maxextents unlimited
48 );
表中有20001000条记录,有二十多个字段,包括几个长度比较大的字段。为了实验测试,只是讲IP字段设置为not null。在UpdateTime上建了默认的B树索引。
三、输入
分为三种场景来讨论,然后比较其结果,然后分析该结果。说明数据库的执行计划的选择其实是足够聪明的。
场景一:
- 表结构:只是在有一个可以为null的列UpdateTime上建了一个索引
- SQL:最简单的Count。
1select count(*) from IDOUBA.App_ApplicationAudit; --count(*)
2select count(PolicyId) from IDOUBA.App_ApplicationAudit; --count(可以null的列)
3select count(IP) from IDOUBA.App_ApplicationAudit; --count(不可null的列)
4select count(UpdateTime) from IDOUBA.App_ApplicationAudit; --count(可以为null并且建了索引的列)
场景二:
- 表结构:和场景一完全相同,只是在有一个可以为null的列UpdateTime上建了一个索引
- SQL:多了个Where子句,在Where子句中涉及到建了索引的可以为null的列。
1select count(*) from IDOUBA.App_ApplicationAudit where updatetime > to_date('2013-05-01 10:23:44', 'yyyy-mm-dd hh24:mi:ss') ; --count(*)
2select count(PolicyId) from IDOUBA.App_ApplicationAudit where updatetime > to_date('2013-05-01 10:23:44', 'yyyy-mm-dd hh24:mi:ss') ; --count(可以null的列)
3select count(IP) from IDOUBA.App_ApplicationAudit where updatetime > to_date('2013-05-01 10:23:44', 'yyyy-mm-dd hh24:mi:ss') ; --count(不可null的列)
4select count(UpdateTime) from y IDOUBA.App_ApplicationAudit where updatetime > to_date('2013-05-01 10:23:44', 'yyyy-mm-dd hh24:mi:ss') ; --count(可以为null并且建了索引的列)
场景三:
- 表结构:除了有一个可以为null的列UpdateTime上建了一个索引外,设置另外一列IpNum列为not null,并且在其上创建索引。
- SQL:最简单的Count。
1select count(*) from IDOUBA.App_ApplicationAudit; --count(*)
2select count(PolicyId) from IDOUBA.App_ApplicationAudit; --count(可以null的列)
3select count(IP) from IDOUBA.App_ApplicationAudit; --count(不可null的列)
4select count(UpdateTime) from IDOUBA.App_ApplicationAudit; --count(可以为null并且建了索引的列)
四、实验结果
场景/Count类型 | Count(*) | Count(PolicyId) 非索引可null的列 | Count(IP)非索引not null 的列 | Count(Updatetime)可以null的索引列 | Count(IPNum) not null 的索引列 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
执行时间(秒) | 物理读 | 执行操作 | 执行时间(秒) | 物理读 | 执行操作 | 执行时间(秒) | 物理读 | 执行操作 | 执行时间(秒) | 物理读 | 执行操作 | 执行时间(秒) | 物理读 physical reads | 执行操作 | |
场景一 | 50.98 | 51671 | 表扫描 | 47.43 | 451672 | 表扫描 | 47.73 | 451672 | 表扫描 | 8.7 | 82393 | UpdateTime上快速索引扫描 | 无 | 无 | 无 |
场景二 | 9.28 | 82395 | UpdateTime上快速索引扫描 | 48.12 | 451673 | 表扫描 | 9.65 | 82428 | UpdateTime上快速索引扫描 | 9.03 | 82394 | UpdateTime上快速索引扫描 | 无 | 无 | 无 |
场景三 | 5.14 | 50224 | IpNum上快速索引扫描 | 47.89 | 451672 | 表扫描 | 2.25 | 15153 | IpNum上快速索引扫描 | 9.06 | 82393 | UpdateTime上快速索引扫描 | 3.2 | 82393 | IpNum上快速索引扫描 |
五、结果分析
其实观察查询计划,也就两种,一种快速索引扫描(INDEX FAST FULL SCAN),另外一种是全表扫描(TABLE ACCESS FULL|)。因为实验表中数据量还是不算小,有两千多万,两者的对比还是比较明显。主要体现在总的执行时间,和物理读取上面,差着一个量级。下面对表中的执行结果逐个进行总结和解释。
场景一:
当表中只在一个可以null的列上建索引的情况下。观察到count(*) 、count not null的列count(IP),count 可以null的列PolicyId的count(PolicyId)的效果一样都是走全表扫描(TABLE ACCESS FULL|);而对于count建了索引并且列可以null的列count(UpdateTime),走快速索引扫描(INDEX FAST FULL SCAN)。即只在索引列UpdateTime上, count会走快速索引扫描(INDEX FAST FULL SCAN),其他都是全表扫描。
解释:因为oracle不会索引null,因此扫描该列上的索引只能知道该列上非null的值,而count(*) 和count(非空列)都是统计总行数,从索引上不能获得该信息,只能全表扫描。而count(可空列)就更不能参照该索引了,建了索引的可空列上非null的行数,和在count的可空列上非null的行数没有任何关系,因此也只能全表扫描了。
场景二:
比场景一where子句中包含了可以null的列update的条件where updatetime > to_date(’2013-05-01 10:23:44′, ‘yyyy-mm-dd hh24:mi:ss’) 。观察到count(*)和count not null的列count(IP)和count UpdateTime一样都走updatetime上的快速索引扫描(INDEX FAST FULL SCAN);而count 可null列PolicyId的count(PolicyId)还是全表扫描。
解释:满足类似于pdatetime > to_date(’2013-05-01 10:23:44′, ‘yyyy-mm-dd hh24:mi:ss’)这样可空列上的条件,其实隐含的意思是满足该条件并且该列上取值不为null的行的行数。则在这列上的count,count(*),在其他非null列上的count,表达的都是这个意思,因此可以利用该索引来做索引扫描。而在另外一个可null的列上的count是表示满足该where条件同时在count列上值非null的记录行数,索引列上不为空的行可能在该列上为空,因此不能参照那个索引,只能全表扫描。
场景三:
当表中存在一个not null的列IpNum上建了索引。观察到count(*)和count(IP)在非空索引上快速索引扫描(INDEX FAST FULL SCAN),但是count(ProjectId)还是走原来的全表扫描。即:当表上在一个not null列上建了索引,则只有可Null的列的count走全表扫描,其他的都会走这个建了索引的no null 列的快速索引扫描(INDEX FAST FULL SCAN)。
解释:有一个not null的列上建了索引,则这个索引上的记录数就是表的行数,count(*),count(非空列)都是数行数。但是count(可null 列)是数这个列上不为空的记录数,因此不能参照索引,只能全表扫描了。
六、总结
在Oracle中,Count(Column)是计算Column上不为该列取值不为null的行数,Count一个not null的列其实就是总行数。而Count(*)是不区分null或者not null就是所有记录行数。因此二者语义是一样的,实验也证明了在各种情况下其执行计划总是一样的。对于这两种Count,表上无论哪个索引能提供这样的语义(在例子中场景二和场景三的两个不同索引分别提供了这样的语义),就会走这个索引。如果没有索引能提供这个语义,就不得不走全表扫描了。而Count一个可以为null的列,因为要数本列上到底有多少行的值不为null,因此不能参照别的列,必须在该列上数数,如果该列上有索引,则会在该列的索引上扫描,如果该列上没有索引,则不得不全表扫描。
附:各种场景的执行计划
- 只是在有一个可以为null的列UpdateTime上建了一个索引的Count(*)
1SQL> select count(*) from IDOUBA.App_ApplicationAudit;
1COUNT(*)
2----------
3 20001000
4已用时间: 00: 00: 50.98
5执行计划
6----------------------------------------------------------
7Plan hash value: 2649150711
8-----------------------------------------------------------------------------------
9| Id | Operation | Name | Rows | Cost (%CPU)| Time |
10-----------------------------------------------------------------------------------
11| 0 | SELECT STATEMENT | | 1 | 99985 (2)| 00:20:00 |
12| 1 | SORT AGGREGATE | | 1 | | |
13| 2 | TABLE ACCESS FULL| APP_APPLICATIONAUDIT | 19M| 99985 (2)| 00:20:00 |
14-----------------------------------------------------------------------------------
15统计信息
16----------------------------------------------------------
17 166 recursive calls
18 0 db block gets
19 451721 consistent gets
20 451671 physical reads
21 0 redo size
22 410 bytes sent via SQL*Net to client
23 385 bytes received via SQL*Net from client
24 2 SQL*Net roundtrips to/from client
25 5 sorts (memory)
26 0 sorts (disk)
27 1 rows processed
- 只是在有一个可以为null的列UpdateTime上建了一个索引的Count一个可以null的列policyId
1SQL> select count(policyId) from IDOUBA.App_ApplicationAudit;
1COUNT(POLICYID)
2---------------
3 20001000
4已用时间: 00: 00: 47.43
5执行计划
6----------------------------------------------------------
7Plan hash value: 2649150711
8-------------------------------------------------------------------------------------------
9| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
10-------------------------------------------------------------------------------------------
11| 0 | SELECT STATEMENT | | 1 | 2 | 100K (2)| 00:20:02 |
12| 1 | SORT AGGREGATE | | 1 | 2 | | |
13| 2 | TABLE ACCESS FULL| APP_APPLICATIONAUDIT | 19M| 38M| 100K (2)| 00:20:02 |
14-------------------------------------------------------------------------------------------
15统计信息
16----------------------------------------------------------
17 1 recursive calls
18 0 db block gets
19 451701 consistent gets
20 451672 physical reads
21 0 redo size
22 417 bytes sent via SQL*Net to client
23 385 bytes received via SQL*Net from client
24 2 SQL*Net roundtrips to/from client
25 0 sorts (memory)
26 0 sorts (disk)
27 1 rows processed
- 只是在有一个可以为null的列UpdateTime上建了一个索引的Count一个可以null的索引列updatetime:Count(UpdateTime)
1SQL> select count(updatetime) from IDOUBA.App_ApplicationAudit;
1COUNT(UPDATETIME)
2-----------------
3 20001000
4已用时间: 00: 00: 08.70
5执行计划
6----------------------------------------------------------
7Plan hash value: 3909306724
8------------------------------------------------------------------------------------------
9| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
10------------------------------------------------------------------------------------------
11| 0 | SELECT STATEMENT | | 1 | 8 | 18204 (3)| 00:03:39 |
12| 1 | SORT AGGREGATE | | 1 | 8 | | |
13| 2 | INDEX FAST FULL SCAN| INDEX_UPDATETIME | 19M| 152M| 18204 (3)| 00:03:39 |
14------------------------------------------------------------------------------------------
15统计信息
16----------------------------------------------------------
17 164 recursive calls
18 0 db block gets
19 82448 consistent gets
20 82393 physical reads
21 0 redo size
22 419 bytes sent via SQL*Net to client
23 385 bytes received via SQL*Net from client
24 2 SQL*Net roundtrips to/from client
25 5 sorts (memory)
26 0 sorts (disk)
27 1 rows processed
- 只是在有一个可以为null的列UpdateTime上建了一个索引的Count一个not null的非索引列IP:Count(IP)
1SQL> select count(Ip) from IDOUBA.App_ApplicationAudit;
1COUNT(IP)
2----------
3 20001000
4已用时间: 00: 00: 47.73
5执行计划
6----------------------------------------------------------
7Plan hash value: 2649150711
8-----------------------------------------------------------------------------------
9| Id | Operation | Name | Rows | Cost (%CPU)| Time |
10-----------------------------------------------------------------------------------
11| 0 | SELECT STATEMENT | | 1 | 99985 (2)| 00:20:00 |
12| 1 | SORT AGGREGATE | | 1 | | |
13| 2 | TABLE ACCESS FULL| APP_APPLICATIONAUDIT | 19M| 99985 (2)| 00:20:00 |
14-----------------------------------------------------------------------------------
15统计信息
16----------------------------------------------------------
17 218 recursive calls
18 0 db block gets
19 451730 consistent gets
20 451672 physical reads
21 0 redo size
22 411 bytes sent via SQL*Net to client
23 385 bytes received via SQL*Net from client
24 2 SQL*Net roundtrips to/from client
25 5 sorts (memory)
26 0 sorts (disk)
27 1 rows processed
- 只是在有一个可以为null的列UpdateTime上建了一个索引,Query的Where子句中包含该UpdateTime列的条件where updatetime > to_date(’2013-05-01 10:23:44′, ‘yyyy-mm-dd hh24:mi:ss’) ,Count(*)
1SQL> select count(*) from IDOUBA.App_ApplicationAudit where updatetime > to_date('2013-05-01 10:23:44', 'yyyy-mm-dd hh24:mi:ss') ;
1COUNT(*)
2----------
3 20001000
4已用时间: 00: 00: 09.28
5执行计划
6----------------------------------------------------------
7Plan hash value: 3909306724
8------------------------------------------------------------------------------------------
9| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
10------------------------------------------------------------------------------------------
11| 0 | SELECT STATEMENT | | 1 | 8 | 18373 (4)| 00:03:41 |
12| 1 | SORT AGGREGATE | | 1 | 8 | | |
13|* 2 | INDEX FAST FULL SCAN| INDEX_UPDATETIME | 19M| 152M| 18373 (4)| 00:03:41 |
14------------------------------------------------------------------------------------------
15Predicate Information (identified by operation id):
16---------------------------------------------------
17 2 - filter("UPDATETIME">TO_DATE('2013-05-01 10:23:44', 'yyyy-mm-dd
18 hh24:mi:ss'))
19统计信息
20----------------------------------------------------------
21 227 recursive calls
22 0 db block gets
23 82464 consistent gets
24 82395 physical reads
25 0 redo size
26 410 bytes sent via SQL*Net to client
27 385 bytes received via SQL*Net from client
28 2 SQL*Net roundtrips to/from client
29 5 sorts (memory)
30 0 sorts (disk)
31 1 rows processed</pre>
- 只是在有一个可以为null的列UpdateTime上建了一个索引,Query的Where子句中包含该UpdateTime列的条件where updatetime > to_date(’2013-05-01 10:23:44′, ‘yyyy-mm-dd hh24:mi:ss’) 。Count一个可以null的列PolicyId:Count(PolicyId)
1SQL> select count(policyId) from IDOUBA.App_ApplicationAudit where updatetime > to_date('2013-05-01 10:23:44', 'yyyy-mm-dd hh24:mi:ss') ;
1COUNT(POLICYID)
2---------------
3 20001000
4已用时间: 00: 00: 48.12
5执行计划
6----------------------------------------------------------
7Plan hash value: 2649150711
8-------------------------------------------------------------------------------------------
9| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
10-------------------------------------------------------------------------------------------
11| 0 | SELECT STATEMENT | | 1 | 10 | 101K (3)| 00:20:20 |
12| 1 | SORT AGGREGATE | | 1 | 10 | | |
13|* 2 | TABLE ACCESS FULL| APP_APPLICATIONAUDIT | 19M| 190M| 101K (3)| 00:20:20 |
14-------------------------------------------------------------------------------------------
15Predicate Information (identified by operation id):
16---------------------------------------------------
17 2 - filter("UPDATETIME">TO_DATE('2013-05-01 10:23:44', 'yyyy-mm-dd hh24:mi:ss'))
18统计信息
19----------------------------------------------------------
20 227 recursive calls
21 0 db block gets
22 451737 consistent gets
23 451673 physical reads
24 0 redo size
25 417 bytes sent via SQL*Net to client
26 385 bytes received via SQL*Net from client
27 2 SQL*Net roundtrips to/from client
28 5 sorts (memory)
29 0 sorts (disk)
30 1 rows processed
- 只是在有一个可以为null的列UpdateTime上建了一个索引,Query的Where子句中包含该UpdateTime列的条件where updatetime > to_date(’2013-05-01 10:23:44′, ‘yyyy-mm-dd hh24:mi:ss’) 。Count一个not null的列IP:Count(IP)
1 SQL> select count(ip) from IDOUBA.App_ApplicationAudit where updatetime > to_date('2013-05-01 10:23:44', 'yyyy-mm-dd hh24:mi:ss') ;
1COUNT(IP)
2----------
3 20001000
4已用时间: 00: 00: 09.65
5
6执行计划
7----------------------------------------------------------
8Plan hash value: 3909306724
9------------------------------------------------------------------------------------------
10| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
11------------------------------------------------------------------------------------------
12| 0 | SELECT STATEMENT | | 1 | 8 | 18373 (4)| 00:03:41 |
13| 1 | SORT AGGREGATE | | 1 | 8 | | |
14|* 2 | INDEX FAST FULL SCAN| INDEX_UPDATETIME | 19M| 152M| 18373 (4)| 00:03:41 |
15------------------------------------------------------------------------------------------
16Predicate Information (identified by operation id):
17---------------------------------------------------
18 2 - filter("UPDATETIME">TO_DATE('2013-05-01 10:23:44', 'yyyy-mm-dd hh24:mi:ss'))
19统计信息
20----------------------------------------------------------
21 1 recursive calls
22 0 db block gets
23 82428 consistent gets
24 82393 physical reads
25 0 redo size
26 411 bytes sent via SQL*Net to client
27 385 bytes received via SQL*Net from client
28 2 SQL*Net roundtrips to/from client
29 0 sorts (memory)
30 0 sorts (disk)
31 1 rows processed
- 只是在有一个可以为null的列UpdateTime上建了一个索引,Query的Where子句中包含该UpdateTime列的条件where updatetime > to_date(’2013-05-01 10:23:44′, ‘yyyy-mm-dd hh24:mi:ss’) 。Count该可以 null的索引列UpdateTime:Count(UpdateTime)
1SQL> select count(updatetime) from IDOUBA.App_ApplicationAudit where updatetime > to_date('2013-05-01 10:23:44', 'yyyy-mm-dd hh24:mi:ss') ;
1COUNT(UPDATETIME)
2-----------------
3 20001000
4已用时间: 00: 00: 09.03
5执行计划
6----------------------------------------------------------
7Plan hash value: 3909306724
8------------------------------------------------------------------------------------------
9| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
10------------------------------------------------------------------------------------------
11| 0 | SELECT STATEMENT | | 1 | 8 | 18204 (3)| 00:03:39 |
12| 1 | SORT AGGREGATE | | 1 | 8 | | |
13| 2 | INDEX FAST FULL SCAN| INDEX_UPDATETIME | 19M| 152M| 18204 (3)| 00:03:39 |
14------------------------------------------------------------------------------------------
15统计信息
16----------------------------------------------------------
17 185 recursive calls
18 0 db block gets
19 82460 consistent gets
20 82394 physical reads
21 0 redo size
22 419 bytes sent via SQL*Net to client
23 385 bytes received via SQL*Net from client
24 2 SQL*Net roundtrips to/from client
25 5 sorts (memory)
26 0 sorts (disk)
27 1 rows processed
- 在一个not null的列IPNum创建索引count(*)
1SQL> select count(*) from IDOUBA.App_ApplicationAudit;
1COUNT(*)
2----------
3 20001000
4已用时间: 00: 00: 05.14
5执行计划
6----------------------------------------------------------
7Plan hash value: 2581539037
8-----------------------------------------------------------------------------
9| Id | Operation | Name | Rows | Cost (%CPU)| Time |
10-----------------------------------------------------------------------------
11| 0 | SELECT STATEMENT | | 1 | 11435 (5)| 00:02:18 |
12| 1 | SORT AGGREGATE | | 1 | | |
13| 2 | INDEX FAST FULL SCAN| INDEX_IPNUM | 19M| 11435 (5)| 00:02:18 |
14-----------------------------------------------------------------------------
15统计信息
16----------------------------------------------------------
17 1 recursive calls
18 0 db block gets
19 50253 consistent gets
20 50224 physical reads
21 0 redo size
22 410 bytes sent via SQL*Net to client
23 385 bytes received via SQL*Net from client
24 2 SQL*Net roundtrips to/from client
25 0 sorts (memory)
26 0 sorts (disk)
27 1 rows processed
10 在一个not null的列IPNum创建索引。Count可null的列PolicyId:Count(PolicyId)
1SQL> select count(policyId) from IDOUBA.App_ApplicationAudit;
1COUNT(POLICYID)
2---------------
3 20001000
4已用时间: 00: 00: 47.89
5执行计划
6----------------------------------------------------------
7Plan hash value: 2649150711
8-------------------------------------------------------------------------------------------
9| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
10-------------------------------------------------------------------------------------------
11| 0 | SELECT STATEMENT | | 1 | 2 | 100K (2)| 00:20:02 |
12| 1 | SORT AGGREGATE | | 1 | 2 | | |
13| 2 | TABLE ACCESS FULL| APP_APPLICATIONAUDIT | 19M| 38M| 100K (2)| 00:20:02 |
14-------------------------------------------------------------------------------------------
15统计信息
16----------------------------------------------------------
17 1 recursive calls
18 0 db block gets
19 451701 consistent gets
20 451672 physical reads
21 0 redo size
22 417 bytes sent via SQL*Net to client
23 385 bytes received via SQL*Net from client
24 2 SQL*Net roundtrips to/from client
25 0 sorts (memory)
26 0 sorts (disk)
27 1 rows processed
11 在一个not null的列IPNum创建索引。Count not null的列IP:Count(IP)
1SQL> select count(Ip) from IDOUBA.App_ApplicationAudit;
1COUNT(IP)
2----------
3 20001000
4已用时间: 00: 00: 02.25
5执行计划
6----------------------------------------------------------
7Plan hash value: 2581539037
8-----------------------------------------------------------------------------
9| Id | Operation | Name | Rows | Cost (%CPU)| Time |
10-----------------------------------------------------------------------------
11| 0 | SELECT STATEMENT | | 1 | 11435 (5)| 00:02:18 |
12| 1 | SORT AGGREGATE | | 1 | | |
13| 2 | INDEX FAST FULL SCAN| INDEX_IPNUM | 19M| 11435 (5)| 00:02:18 |
14-----------------------------------------------------------------------------
15统计信息
16----------------------------------------------------------
17 196 recursive calls
18 0 db block gets
19 50290 consistent gets
20 15153 physical reads
21 0 redo size
22 411 bytes sent via SQL*Net to client
23 385 bytes received via SQL*Net from client
24 2 SQL*Net roundtrips to/from client
25 5 sorts (memory)
26 0 sorts (disk)
27 1 rows processed
12 在一个not null的列IPNum创建索引。Count另外一个建了索引的可null的列UpdateTime:Count(UpdateTime)
1SQL> select count(updatetime) from IDOUBA.App_ApplicationAudit;
1COUNT(UPDATETIME)
2-----------------
3 20001000
4已用时间: 00: 00: 09.06
5执行计划
6----------------------------------------------------------
7Plan hash value: 3909306724
8------------------------------------------------------------------------------------------
9| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
10------------------------------------------------------------------------------------------
11| 0 | SELECT STATEMENT | | 1 | 8 | 18204 (3)| 00:03:39 |
12| 1 | SORT AGGREGATE | | 1 | 8 | | |
13| 2 | INDEX FAST FULL SCAN| INDEX_UPDATETIME | 19M| 152M| 18204 (3)| 00:03:39 |
14------------------------------------------------------------------------------------------
15统计信息
16----------------------------------------------------------
17 1 recursive calls
18 0 db block gets
19 82428 consistent gets
20 82393 physical reads
21 0 redo size
22 419 bytes sent via SQL*Net to client
23 385 bytes received via SQL*Net from client
24 2 SQL*Net roundtrips to/from client
25 0 sorts (memory)
26 0 sorts (disk)
27 1 rows processed