Bonjour,
Qu'est ce qui est le plus performant (ou du moins le moins couteux !)
ouCode:select count(*) from X;
Question bête mais le débat fait rage dans ma boite ! :)Code:select count(1) from X;
Merci !
Version imprimable
Bonjour,
Qu'est ce qui est le plus performant (ou du moins le moins couteux !)
ouCode:select count(*) from X;
Question bête mais le débat fait rage dans ma boite ! :)Code:select count(1) from X;
Merci !
C'est pareils.
Moi, je préfère "count (1)" - car c'est plus joli :D.
je me demande si COUNT(PK) n'est pas le plus rapide...
non, pourquoi?
Code:
1
2
3
4
5
6
7
8
9
10 create table t1 (a number constraint t1a primary key); create table t2 (b number constraint t2b primary key); insert into t1 (a) select level from dual connect by level <= 10000; insert into t2 (b) select level from dual connect by level <= 100; exec dbms_stats.gather_table_stats (user, 'T1') exec dbms_stats.gather_table_stats (user, 'T2')
les mêmes résultats (10g R1):Code:
1
2
3
4
5
6
7
8
9
10
11 select count (a) from t1, t2 where b (+) = a; select count (1) from t1, t2 where b (+) = a; select count (*) from t1, t2 where b (+) = a;
Code:
1
2
3
4
5
6
7
8
9
10
11 10000 ------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 6 | 13 (54)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | 6 | | | | 2 | NESTED LOOPS OUTER | | 10000 | 60000 | 13 (54)| 00:00:01 | | 3 | INDEX FAST FULL SCAN| T1A | 10000 | 30000 | 6 (0)| 00:00:01 | |* 4 | INDEX UNIQUE SCAN | T2B | 1 | 3 | 0 (0)| 00:00:01 | -------------------------------------------------------------------------------
Pourquoi ? Il me semblait que lorsque l'on spécifiait la PK, le décompte se faisait sur l'index correspondant.
Attention, méfiez-vous des count(<champ>), ce n'est pas anodin !
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 WITH Table1 AS ( select 1 AS pk, 'A' as code from dual union select 2, 'B' from dual union select 3, 'C' from dual ), Table2 AS ( select 2 AS pk, 'A' AS code from dual union select 8, 'C' from dual ) select count(1), count(*), count(t1.pk), count(t2.pk) from Table1 t1 LEFT OUTER JOIN Table2 t2 ON t2.code = t1.code
Donc si je comprend bien c'est du pareil au même
Code:
1
2
3 select * from T1; select 1 from T1; select PK from T1;
Bon ben au moins tout le monde sera content comme ça dans ma boite !
En tout cas merci à tous pour votre aide !!!
P.S : Je ne connaissais pas l'instruction "connect BY" ; Intéressante !
Salut !
Tu as peut être saisi l'astuce, mais je préfère préciser :
C'est pareil seulement si ta colonne est déclarée en NOT NULL.
=> comme tu as pu le voir dans les différents exemples COUNT(column) compte toutes les lignes pour lesquelles la valeur est non nulle...
Et donc, ça fait un peu de boulot supplémentaire au SGBD, surtout si la valeur n'est pas l'index (puisqu'il faut alors accéder aux données).
Par pk (là encore, tu l'avais peut être deviné), le monsieur désignait la colonne qui est primary key...
Si j'ai bien compris, COUNT(*) et COUNT(1) ont la même performance, tandis que COUNT(colonne nullable) sont légèrement moins bons ?
Par contre, je n'ai pas compris si COUNT(PK ou autre colonne NOT NULL) était aussi bon que COUNT(*) ?
Count(*) ramenant les NULL, il ne passe donc par aucun index, raison pour laquelle je pensais qu'il était un poil moins rapide.
La différence peut être grande:
Code:
1
2
3
4
5
6
7
8
9
10
11
12 create table t1 ( a number constraint t1a primary key, b varchar2 (4000), c varchar2 (4000), d varchar2 (4000)); insert into t1 (a, b, c, d) select level, rpad ('x', 4000, 'x'), rpad ('x', 4000, 'x'), rpad ('x', 4000, 'x') from dual connect by level <= 10000; insert into t1 (a) values (10001); exec dbms_stats.gather_table_stats (user, 'T1')
Code:
1
2
3
4
5
6
7
8
9
10
11 SQL> select count (a) from t1; 10001 Uplynulo: 00:00:00.00 SQL> select count (b) from t1; 10000 Uplynulo: 00:00:03.62 SQL> select count (1) from t1; 10001 Uplynulo: 00:00:00.00
pour PK (de la table principale!) - ouiCitation:
Par contre, je n'ai pas compris si COUNT(PK ou autre colonne NOT NULL) était aussi bon que COUNT(*) ?
pour colonne NOT NULL en général - non
Ce n'est pas une question de performance, c'est une question de résultat !
Count(colonne) te renvoie le nb de lignes pour lesquelles la colonne est NOT NULL.
Il vaut mieux pas forcer Oracle à lire des données en particulier..
Donc pas de count(PK), count(colonne NOT NULL) etc...
Simplement parce que si ta requête fait qu'Oracle n'accède pas à ces données
, il est obligé d'aller les rechercher (Exemple tu fais juste un where sur une colonne indexée, Oracle ne lira que cet index, pas l'index de la PK)
Donc en résumé : Count(1) = count(*) : A utiliser.
Count(colonne) à n'utiliser que pour compter réellement le nb d'occurrences NOT NULL.
Euh... ben moi aussi alors ! :mouarf::mouarf:
un petit essai:
Les commandes suivantes ont les mêmes plans:Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14 create table t1 ( a number constraint t1a primary key, x number not null, b varchar2 (4000) not null, c varchar2 (4000), d varchar2 (4000)); create index t1x on t1 (x); insert into t1 (a, x, b, c, d) select level, level, rpad ('x', 4000, 'x'), rpad ('x', 4000, 'x'), rpad ('x', 4000, 'x') from dual connect by level <= 10000; exec dbms_stats.gather_table_stats (user, 'T1')
Code:
1
2
3
4
5
6
7
8
9
10
11
12 select count (a) from t1 where x <= 5000; select count (x) from t1 where x <= 5000; select count (1) from t1 where x <= 5000; select count (b) from t1 where x <= 5000; ------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | 1 | 4 | 6 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | 4 | | | |* 2 | INDEX FAST FULL SCAN| T1X | 5000 | 20000 | 6 (0)| 00:00:01 | ------------------------------------------------------------------------------
Cela n'est-il pas simplement du à l'existence d'une clause Where commune ?