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,如需转载请自行联系原作者

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值