Oracle count哪种写法更快

简介:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
1)创建测试表
test@CISCOSYS>  create  table  as  select  from  dba_objects;
表已创建。
test@CISCOSYS>  update  set  object_id =rownum ;
已更新50967行。
2)使用 count (*)进行统计
test@CISCOSYS>  select  count (*)  from  t;
COUNT (*)
----------
50967
已用时间:  00: 00: 00.01
执行计划
----------------------------------------------------------
Plan hash value: 2966233522
-------------------------------------------------------------------
| Id  | Operation          |  Name  Rows   | Cost (%CPU)|  Time      |
-------------------------------------------------------------------
|   0 |  SELECT  STATEMENT   |      |     1 |   161   (2)| 00:00:02 |
|   1 |  SORT AGGREGATE    |      |     1 |            |          |
|   2 |    TABLE  ACCESS  FULL | T    | 44475 |   161   (2)| 00:00:02 |
-------------------------------------------------------------------
Note
-----
dynamic  sampling used  for  this statement
统计信息
----------------------------------------------------------
4  recursive calls
0  db block gets
764  consistent gets
0  physical reads
0  redo  size
410  bytes sent via SQL*Net  to  client
385  bytes received via SQL*Net  from  client
2  SQL*Net roundtrips  to / from  client
0  sorts (memory)
0  sorts (disk)
1   rows  processed
3)使用 COUNT (列)进行统计
test@CISCOSYS>  select  count (*)  from  t;
COUNT (*)
----------
50967
已用时间:  00: 00: 00.01
执行计划
----------------------------------------------------------
Plan hash value: 2966233522
-------------------------------------------------------------------
| Id  | Operation          |  Name  Rows   | Cost (%CPU)|  Time      |
-------------------------------------------------------------------
|   0 |  SELECT  STATEMENT   |      |     1 |   161   (2)| 00:00:02 |
|   1 |  SORT AGGREGATE    |      |     1 |            |          |
|   2 |    TABLE  ACCESS  FULL | T    | 44475 |   161   (2)| 00:00:02 |
-------------------------------------------------------------------
Note
-----
dynamic  sampling used  for  this statement
统计信息
----------------------------------------------------------
4  recursive calls
0  db block gets
764  consistent gets
0  physical reads
0  redo  size
410  bytes sent via SQL*Net  to  client
385  bytes received via SQL*Net  from  client
2  SQL*Net roundtrips  to / from  client
0  sorts (memory)
0  sorts (disk)
1   rows  processed
解释一下 :物理读为0,是因为创建表的时候,数据已经载入 load  buffer.
可以使用
test@CISCOSYS>  alter  system flush buffer_cache;
通过比较 COUNT (*) 和 Count (列) ,两种情况的COST 是完全一样的。
继续试验!!!
为表创建索引
test@CISCOSYS>  create  index  idx_t_id  on  t(object_id);
索引已创建。
test@CISCOSYS>  alter  system flush buffer_cache;
系统已更改。
test@CISCOSYS>  select  count (*)  from  t;
COUNT (*)
----------
50967
已用时间:  00: 00: 00.26
执行计划
----------------------------------------------------------
Plan hash value: 2966233522
-------------------------------------------------------------------
| Id  | Operation          |  Name  Rows   | Cost (%CPU)|  Time      |
-------------------------------------------------------------------
|   0 |  SELECT  STATEMENT   |      |     1 |   161   (2)| 00:00:02 |
|   1 |  SORT AGGREGATE    |      |     1 |            |          |
|   2 |    TABLE  ACCESS  FULL | T    | 44475 |   161   (2)| 00:00:02 |
-------------------------------------------------------------------
Note
-----
dynamic  sampling used  for  this statement
统计信息
----------------------------------------------------------
5  recursive calls
0  db block gets
765  consistent gets
705  physical reads
0  redo  size
410  bytes sent via SQL*Net  to  client
385  bytes received via SQL*Net  from  client
2  SQL*Net roundtrips  to / from  client
0  sorts (memory)
0  sorts (disk)
1   rows  processed
test@CISCOSYS>  select  count (object_id)  from  t;
COUNT (OBJECT_ID)
----------------
50967
已用时间:  00: 00: 00.09
执行计划
----------------------------------------------------------
Plan hash value: 3570898368
--------------------------------------------------------------------------------
--
| Id  | Operation             |  Name      Rows   | Bytes | Cost (%CPU)|  Time
|
--------------------------------------------------------------------------------
--
|   0 |  SELECT  STATEMENT      |          |     1 |    13 |    30   (4)| 00:00:01
|
|   1 |  SORT AGGREGATE       |          |     1 |    13 |            |
|
|   2 |    INDEX  FAST  FULL  SCAN| IDX_T_ID | 44475 |   564K|    30   (4)| 00:00:01
|
--------------------------------------------------------------------------------
--
Note
-----
dynamic  sampling used  for  this statement
统计信息
----------------------------------------------------------
4  recursive calls
0  db block gets
181  consistent gets
477  physical reads
0  redo  size
418  bytes sent via SQL*Net  to  client
385  bytes received via SQL*Net  from  client
2  SQL*Net roundtrips  to / from  client
0  sorts (memory)
0  sorts (disk)
1   rows  processed
在这里,用 COUNT (列)比 COUNT (*)要快。通过比较执行计划。可以看出 COUNT (*)不能用到索引,而 COUNT (列)可以
继续试验!!!
将键值设为非空
test@CISCOSYS>  alter  table  modify  object_id   not   null ;
表已更改。
已用时间:  00: 00: 01.34
test@CISCOSYS>  alter  system flush buffer_cache;
系统已更改。
已用时间:  00: 00: 00.01
test@CISCOSYS>  select  count (*)  from  t;
COUNT (*)
----------
50967
已用时间:  00: 00: 00.31
执行计划
----------------------------------------------------------
Plan hash value: 3570898368
--------------------------------------------------------------------------
| Id  | Operation             |  Name      Rows   | Cost (%CPU)|  Time      |
--------------------------------------------------------------------------
|   0 |  SELECT  STATEMENT      |          |     1 |    30   (4)| 00:00:01 |
|   1 |  SORT AGGREGATE       |          |     1 |            |          |
|   2 |    INDEX  FAST  FULL  SCAN| IDX_T_ID | 44475 |    30   (4)| 00:00:01 |
--------------------------------------------------------------------------
Note
-----
dynamic  sampling used  for  this statement
统计信息
----------------------------------------------------------
205  recursive calls
0  db block gets
213  consistent gets
496  physical reads
0  redo  size
410  bytes sent via SQL*Net  to  client
385  bytes received via SQL*Net  from  client
2  SQL*Net roundtrips  to / from  client
5  sorts (memory)
0  sorts (disk)
1   rows  processed
test@CISCOSYS>  alter  system flush buffer_cache;
系统已更改。
已用时间:  00: 00: 00.04
test@CISCOSYS>  select  count (object_id)  from  t;
COUNT (OBJECT_ID)
----------------
50967
已用时间:  00: 00: 00.20
执行计划
----------------------------------------------------------
Plan hash value: 3570898368
--------------------------------------------------------------------------
| Id  | Operation             |  Name      Rows   | Cost (%CPU)|  Time      |
--------------------------------------------------------------------------
|   0 |  SELECT  STATEMENT      |          |     1 |    30   (4)| 00:00:01 |
|   1 |  SORT AGGREGATE       |          |     1 |            |          |
|   2 |    INDEX  FAST  FULL  SCAN| IDX_T_ID | 44475 |    30   (4)| 00:00:01 |
--------------------------------------------------------------------------
Note
-----
dynamic  sampling used  for  this statement
统计信息
----------------------------------------------------------
4  recursive calls
0  db block gets
181  consistent gets
477  physical reads
0  redo  size
418  bytes sent via SQL*Net  to  client
385  bytes received via SQL*Net  from  client
2  SQL*Net roundtrips  to / from  client
0  sorts (memory)
0  sorts (disk)
1   rows  processed
将一些记录object_id置为 null .
test@CISCOSYS>  alter  table  modify  (object_id number  null );
表已更改。
test@CISCOSYS>  update  set  object_id= null  where  object_id<=10;
已更新10行。
test@CISCOSYS>  select  count (*)  from  t;
COUNT (*)
----------
50967
已用时间:  00: 00: 00.00
test@CISCOSYS>  select  count (object_id)  from  t;
COUNT (OBJECT_ID)
----------------
50957
发现 count (*)和 count (列)记录不一样。也就是说,两个功能上根本不是等价的。
如果一个列上存在索引,且非空。  COUNT (*)和 COUNT (列)功能相当。
反之, COUNT (*) 和 COUNT (列)两者功能本身就功能不同,不应等同对待。

 

基于案例学SQL

 



本文转自 randy_shandong 51CTO博客,原文链接:http://blog.51cto.com/dba10g/1354315,如需转载请自行联系原作者

相关文章
|
运维 Oracle 关系型数据库
Oracle: count STOPKEY 优化
Oracle数据库中select * from test where id> 1000 and rownum=1这样的语句应该怎样优化
518 0
|
Oracle 关系型数据库 MySQL
Mysql,Oracle中 sum、count函数使用条件判断
Mysql,Oracle中 sum、count函数使用条件判断
Mysql,Oracle中 sum、count函数使用条件判断
|
SQL Oracle 关系型数据库
ORACLE的count与空值比较
  今天,一同事问我,有个问题很奇怪,他写的SQL语句不统计null值,怎么一回事,看下面重现:  参与的实验数据: --创建测试表 create table mytab( col1 varchar2(10), col2 varchar2(10), col...
1072 0
|
Oracle 关系型数据库 SQL
oracle count函数
1.  count函数 1.1.  count查询结果 count(*)是以所有字段做count count(1)是以查询结果第一个字段做count,两者的结果是一样的 这里的1应该不是位置变量,相当于给*的结果加一个值为1伪列,再count 1的数量 所以结果和count(*)是一样的,即count(rowid) count(1),你可以理解成有个字段,这个字段就是固定值1,那么也是计算分组下重复的行数。
1107 0
|
SQL Oracle 关系型数据库
[Oracle]-[SORT AGGREGATE]-count与索引
Oracle10g: create table t_count as select * from dba_objects; create index t_count_i on t_count(object_id): 分别用: select count(*) from t_count; select count(object_id) from t_count; select count(object_name) from t_count; 查看是否使用索引对count查询性能起到作用。
915 0
|
Oracle 关系型数据库
oracle中distinct和count函数组合使用
oracle中的distinc关键字和count函数需要经常组合起来使用,例如,如果我们拿到一个仅有员工基本信息的列表,我们希望得到这个公司共有多少个部门。 我们可以这样做: select count(a.deptno) from (select distinct deptno from scott.emp) a; 但这样做太复杂了,我们可以将discint和count函数用在一起 例如: select count(distinct deptno) from scott.emp; 二者效果是一样的。
963 0
|
Oracle 关系型数据库
oracle中的聚合函数count、max、min、sum、avg等等
前面我们介绍了很多oracle中单行函数,在oracle中还存在另一类函数,那就是聚合函数,oracle中的聚合函数非常有用,主要是用来做些统计、平均之类的工作,你必须牢记。 先简单介绍一下几个常用的oracle中的聚合函数。
1658 0
|
21天前
|
存储 Oracle 关系型数据库
Oracle数据库的应用场景有哪些?
【10月更文挑战第15天】Oracle数据库的应用场景有哪些?
139 64
|
11天前
|
SQL Oracle 关系型数据库
Oracle数据库优化方法
【10月更文挑战第25天】Oracle数据库优化方法
23 7