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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值