bonjour,
je voudrais connaître la différence entre le count(*) et le count(1), d'après ce qu'on m'a dit que c'est mieux d'utiliser le count(1) pour des raisons de perfermance car le count (*) remente tous les champs en mémoire
merci
Version imprimable
bonjour,
je voudrais connaître la différence entre le count(*) et le count(1), d'après ce qu'on m'a dit que c'est mieux d'utiliser le count(1) pour des raisons de perfermance car le count (*) remente tous les champs en mémoire
merci
Non c'est faux. Cela revient au même. Ce qui est différent en matière de perf c'est select * ou select 1.
d'accord merci
Bonsoir,
s'il y a une clé primaire sur la table (ou un index unique), il faut faire un count sur la pk.
On aura un balayage que sur l'index(au lieu de la table).
Mais c'est vrai que count(*) ou count(1) ne prendra pas l'index.
CdtCode:
1
2
3 create table test(tst_number number(6), tst_varchar varchar2(200)); create unique index tst_ndx on test(tst_number); select /*+index(test tst_ndx)*/ count(tst_number) from test;
Une instruction "select count(*) ..." peut utiliser un index sans avoir à forcer l'utilisation de l'index par un hint:
Code:
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 dev001> set autot off dev001> dev001> select * from v$version; BANNER ---------------------------------------------------------------- Oracle Database 10g Enterprise Edition Release 10.2.0.2.0 - Prod PL/SQL Release 10.2.0.2.0 - Production CORE 10.2.0.2.0 Production TNS for 32-bit Windows: Version 10.2.0.2.0 - Production NLSRTL Version 10.2.0.2.0 - Production dev001> dev001> drop table t; Table dropped. dev001> dev001> create table t 2 (c1 int primary key, 3 c2 varchar2(100) 4 ); Table created. dev001> dev001> dev001> begin 2 for i in 1.. 10000 3 loop 4 insert into t 5 values (i, to_char(i)); 6 end loop; 7 commit; 8 end; 9 / PL/SQL procedure successfully completed. dev001> show errors No errors. dev001> dev001> exec dbms_stats.gather_table_stats(ownname => 'TEST', tabname => 'T', cascade => true); PL/SQL procedure successfully completed. dev001> dev001> set autot traceonly explain dev001> select count(*) from t; Execution Plan ---------------------------------------------------------- Plan hash value: 1282900848 ----------------------------------------------------------------------------- | Id | Operation | Name | Rows | Cost (%CPU)| Time | ----------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 5 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | | | | 2 | INDEX FAST FULL SCAN| SYS_C003048 | 10000 | 5 (0)| 00:00:01 | -----------------------------------------------------------------------------
Bien vu.
Je ne n'avais jamais fait attention que le count(*) ne fonctionne qu'avec une pk.
Merci
Il n'est pas nécessaire que l'index soit lié à la clé primaire pour qu'il soit prise en compte par le CBO pour exécuter un count(*):
Par contre, il est nécessaire que la colonne indexée ait la contrainte NOT NULL sinon le CBO ne prend pas en compte l'index car les valeurs nulles ne sont pas prises en compte dans un index qui porte sur 1 seule colonne:Code:
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 dev001> dev001> drop table t; Table dropped. dev001> dev001> create table t 2 (c1 int not null, 3 c2 varchar2(100) 4 ); Table created. dev001> dev001> create index tc1 on t(c1); Index created. dev001> dev001> begin 2 for i in 1.. 10000 3 loop 4 insert into t 5 values (i, to_char(i)); 6 end loop; 7 commit; 8 end; 9 / PL/SQL procedure successfully completed. dev001> show errors No errors. dev001> dev001> exec dbms_stats.gather_table_stats(ownname => 'TEST', tabname => 'T', cascade => true); PL/SQL procedure successfully completed. dev001> dev001> set autot traceonly explain dev001> select count(*) from t; Execution Plan ---------------------------------------------------------- Plan hash value: 2963782958 ---------------------------------------------------------------------- | Id | Operation | Name | Rows | Cost (%CPU)| Time | ---------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 5 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | | | | 2 | INDEX FAST FULL SCAN| TC1 | 10000 | 5 (0)| 00:00:01 | ---------------------------------------------------------------------- dev001>
Code:
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 dev001> dev001> drop table t; Table dropped. dev001> dev001> create table t 2 (c1 int, 3 c2 varchar2(100) 4 ); Table created. dev001> dev001> desc t; Name Null? Type ----------------------------------------- -------- ---------------------------- C1 NUMBER(38) C2 VARCHAR2(100) dev001> dev001> create index tc1 on t(c1); Index created. dev001> dev001> begin 2 for i in 1.. 10000 3 loop 4 insert into t 5 values (i, to_char(i)); 6 end loop; 7 commit; 8 end; 9 / PL/SQL procedure successfully completed. dev001> show errors No errors. dev001> dev001> exec dbms_stats.gather_table_stats(ownname => 'TEST', tabname => 'T', ca scade => true); PL/SQL procedure successfully completed. dev001> dev001> set autot traceonly explain dev001> select count(*) from t; Execution Plan ---------------------------------------------------------- Plan hash value: 2966233522 ------------------------------------------------------------------- | Id | Operation | Name | Rows | Cost (%CPU)| Time | ------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 6 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | | | | 2 | TABLE ACCESS FULL| T | 10000 | 6 (0)| 00:00:01 | ------------------------------------------------------------------- dev001>
merci pour la precision