Précédent   Forum des professionnels en informatique > Bases de données > Oracle > Administration
Administration Forum d'entraide sur l'administration du serveur Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 06/11/2007, 17h34   #1
Membre confirmé
 
Inscription : mars 2007
Messages : 750
Détails du profil
Informations forums :
Inscription : mars 2007
Messages : 750
Points : 277
Points : 277
Par défaut Quelle est la meilleure maniere de faire une count?

Bonjour,

j'aurais voulu savoir quel était la meilleure solution pour faire un count dans une table.
Est-ce le count(*)? count(1)? count(PrimaryKey)?
farenheiit est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/11/2007, 17h54   #2
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
ça n'a aucune importance

Moi j'aime bien mettre le nom de la colonne qui m'intéresse et si c'est les lignes sans que la colonne importe alors je mets 1... mais tu peux mettre ce que tu veux
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/11/2007, 17h59   #3
Membre confirmé
 
Inscription : mars 2007
Messages : 750
Détails du profil
Informations forums :
Inscription : mars 2007
Messages : 750
Points : 277
Points : 277
donc y'a pas de meilleure performance avec count(PrimaryKey) plutot que count(*)? 1 DBA y'a quelques années m'avait fait modifier toutes mes lignes de codes pour remplacer les count(*) par des count sur la Primary Key.
farenheiit est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/11/2007, 18h04   #4
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
mais les versions d'Oracle évolue et l'optimiseur avec Il me semble que ça n'a plus d'importance au moins depuis la 8i
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/11/2007, 18h05   #5
Expert Confirmé
 
Avatar de 7gyY9w1ZY6ySRgPeaefZ
 
Homme
dba
Inscription : juillet 2007
Messages : 2 523
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Canada

Informations professionnelles :
Activité : dba

Informations forums :
Inscription : juillet 2007
Messages : 2 523
Points : 3 972
Points : 3 972
C'est depuis la version 8i (peut-être même avant, mais je suis moins sûr de mon coup...) que l'optimiseur s'arrange avec le count( ???? ) et passe outre ce qu'il y a entre parenthèse.
Mais avant, c'est sûr qu'il fallait faire attention !
7gyY9w1ZY6ySRgPeaefZ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/11/2007, 18h16   #6
Membre expérimenté
 
Inscription : juillet 2007
Messages : 495
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : juillet 2007
Messages : 495
Points : 585
Points : 585
On dit toujours que le COUNT(*) est un peu plus lent...

Par contre, attention : un COUNT sur une colonne ne compte pas les enreg. dont la colonne en question vaut null !
__________________
Des chercheurs qui cherchent, on en trouve, mais des chercheurs qui trouvent, on en cherche !
dgi77 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/11/2007, 18h23   #7
Membre confirmé
 
Avatar de DAB.cz
 
Inscription : octobre 2006
Messages : 221
Détails du profil
Informations forums :
Inscription : octobre 2006
Messages : 221
Points : 214
Points : 214
La meilleure solution est ne pas faire un count du tout.
Quelle est la raison pour ça?

DAB
DAB.cz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/11/2007, 18h28   #8
Membre expérimenté
 
Inscription : juillet 2007
Messages : 495
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : juillet 2007
Messages : 495
Points : 585
Points : 585
OK, mais qu'est-ce que tu proposes ?
__________________
Des chercheurs qui cherchent, on en trouve, mais des chercheurs qui trouvent, on en cherche !
dgi77 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/11/2007, 18h29   #9
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
Citation:
Envoyé par dgi77 Voir le message
On dit toujours que le COUNT(*) est un peu plus lent...
et ce n'est pas fondé : http://asktom.oracle.com/pls/asktom/...:1156159920245
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/11/2007, 18h30   #10
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
Citation:
Envoyé par DAB.cz Voir le message
La meilleure solution est ne pas faire un count du tout.
Quelle est la raison pour ça?

DAB
probablement un COUNT avec GROUP BY parce que GROUP BY fait du tri

Sinon, pas de souci
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/11/2007, 18h56   #11
Membre confirmé
 
Avatar de DAB.cz
 
Inscription : octobre 2006
Messages : 221
Détails du profil
Informations forums :
Inscription : octobre 2006
Messages : 221
Points : 214
Points : 214
Peut-être l'order suivant suffit:
Code :
SELECT 1 FROM dual WHERE EXISTS (SELECT 1 FROM matable)
Si le count est inévitable, j'utiliserais count (1), mais je crois "count (*)" et "count (pk)" sont les mêmes (10g). En cas de lenteur inadmissible, on peut estimer (de max. PRIMARY valeur par ex.) ou tenir la valeur (selectée une fois) pour la session ou .....

DAB
DAB.cz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/11/2007, 19h03   #12
Expert Confirmé
 
Avatar de 7gyY9w1ZY6ySRgPeaefZ
 
Homme
dba
Inscription : juillet 2007
Messages : 2 523
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Canada

Informations professionnelles :
Activité : dba

Informations forums :
Inscription : juillet 2007
Messages : 2 523
Points : 3 972
Points : 3 972
Citation:
Envoyé par DAB.cz Voir le message
Si le count est inévitable, j'utiliserais count (1), mais je crois "count (*)" et "count (pk)" sont les mêmes (10g).
C'est exactement la même chose depuis la version 8i !! Cf le lien vers asktom ci-dessus !
7gyY9w1ZY6ySRgPeaefZ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/11/2007, 20h15   #13
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
Citation:
Envoyé par DAB.cz Voir le message
Peut-être l'order suivant suffit:
Code :
SELECT 1 FROM dual WHERE EXISTS (SELECT 1 FROM matable)
ce n'est pas du tout un compte dans ce cas... pour un test d'existence c'est parfait mais si c'est bien le nombre de lignes dont on a besoin le COUNT est indispensable
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/11/2007, 20h59   #14
Membre confirmé
 
Avatar de DAB.cz
 
Inscription : octobre 2006
Messages : 221
Détails du profil
Informations forums :
Inscription : octobre 2006
Messages : 221
Points : 214
Points : 214
oui oui, mais on peut souvent voir:
Code :
1
2
3
SELECT count (1) INTO xcn FROM matable;
IF xcn > 0 then
  ...
(La meilleure solution est ne pas faire un count du tout.)

DAB
DAB.cz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/11/2007, 08h43   #15
Expert Confirmé Sénior


 
Avatar de laurentschneider
 
Homme Laurent Schneider
Administrateur de base de données
Inscription : décembre 2005
Messages : 2 927
Détails du profil
Informations personnelles :
Nom : Homme Laurent Schneider
Localisation : Suisse

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Finance

Informations forums :
Inscription : décembre 2005
Messages : 2 927
Points : 4 549
Points : 4 549
Citation:
Envoyé par dgi77 Voir le message
On dit toujours que le COUNT(*) est un peu plus lent...
on disait aussi que la terre était plate il y a qq temps...

Non, c'est le contraire, dans le pire des cas, COUNT(*) est aussi rapide que count(primarykey) voire COUNT(1), mais le plus efficace et le plus logique est COUNT(*),

Il n'existe à ce jour aucun exemple d'une expression différente et plus rapide que COUNT(*)
__________________
Mon blog : laurentschneider.com
Mon livre : Advanced Oracle SQL Programming
laurentschneider est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/11/2007, 09h19   #16
Expert Confirmé Sénior


 
Avatar de laurentschneider
 
Homme Laurent Schneider
Administrateur de base de données
Inscription : décembre 2005
Messages : 2 927
Détails du profil
Informations personnelles :
Nom : Homme Laurent Schneider
Localisation : Suisse

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Finance

Informations forums :
Inscription : décembre 2005
Messages : 2 927
Points : 4 549
Points : 4 549
Citation:
Envoyé par Jerome_Mtl Voir le message
C'est exactement la même chose depuis la version 8i !! Cf le lien vers asktom ci-dessus !
c'est assez juste car l'optimiseur reconnait les expressions equivalentes à count(*), à savoir COUNT(not_null_expression).

OCM Grégory Guillou a cependant trouvé un exemple en 11g où il vallait mieux employer count(*) ;-)

http://www.pythian.com/blogs/627/ora...unt-and-count1
__________________
Mon blog : laurentschneider.com
Mon livre : Advanced Oracle SQL Programming
laurentschneider est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/11/2007, 09h26   #17
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
Selon la régle qui veut qu'une version d'Oracle ne doit pas être installé avant la 2° release, je pense qu'on va attendre la 11.2 avant de tirer des conclusions

Ceci étant dit, l'exemple est pour le moins étrange... la logique aurait voulu (selon moi ) qu'une vue qui référence des colonnes d'une table soit invalidé quand la table change et pas une vue qui ne compte que les lignes sans se soucier des colonnes... Oracle a ses raisons que la raison n'a pas
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/11/2007, 09h28   #18
Expert Confirmé Sénior


 
Avatar de laurentschneider
 
Homme Laurent Schneider
Administrateur de base de données
Inscription : décembre 2005
Messages : 2 927
Détails du profil
Informations personnelles :
Nom : Homme Laurent Schneider
Localisation : Suisse

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Finance

Informations forums :
Inscription : décembre 2005
Messages : 2 927
Points : 4 549
Points : 4 549
pour démontrer le non-sens de COUNT(PK), voici un petit exemple :

Code :
1
2
3
4
5
6
7
8
9
10
11
SQL> CREATE TABLE t(pk, n, c) AS SELECT rpad(rownum,4000,'x'),0, 
    to_clob(rpad(rownum,4000,'x')) FROM all_objects WHERE rownum<=1000;
TABLE created.
SQL> CREATE INDEX pk ON t(pk);
INDEX created.
SQL> CREATE INDEX n ON t(n);
INDEX created.
SQL> ALTER TABLE t ADD PRIMARY KEY(pk);
TABLE altered.
SQL> ALTER TABLE t MODIFY (n NOT NULL);
TABLE altered.
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
SQL> SET autotrace ON
SQL> SELECT count(pk) FROM t;
 COUNT(PK)
----------
      1000
Execution Plan
----------------------------------------------------------------------
| Id  | Operation             | Name | Rows  | Cost (%CPU)| Time     |
----------------------------------------------------------------------
|   0 | SELECT STATEMENT      |      |     1 |     3   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE       |      |     1 |            |          |
|   2 |   INDEX FAST FULL SCAN| N    |   921 |     3   (0)| 00:00:01 |
----------------------------------------------------------------------
Comme on le voit, COUNT(PK) n'utilise pas le gros index PK varchar2(4000) de la clé primaire mais bien le petit index N number. Donc COUNT(PK) est identifié comme un count(*) et traduit par l'optimiseur.

__________________
Mon blog : laurentschneider.com
Mon livre : Advanced Oracle SQL Programming
laurentschneider est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/11/2007, 09h30   #19
Expert Confirmé Sénior


 
Avatar de laurentschneider
 
Homme Laurent Schneider
Administrateur de base de données
Inscription : décembre 2005
Messages : 2 927
Détails du profil
Informations personnelles :
Nom : Homme Laurent Schneider
Localisation : Suisse

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Finance

Informations forums :
Inscription : décembre 2005
Messages : 2 927
Points : 4 549
Points : 4 549
Citation:
Envoyé par orafrance Voir le message
Ceci étant dit, l'exemple est pour le moins étrange... la logique aurait voulu (selon moi ) qu'une vue qui référence des colonnes d'une table soit invalidé quand la table change et pas une vue qui ne compte que les lignes sans se soucier des colonnes... Oracle a ses raisons que la raison n'a pas
Oui, Oracle aura dû constater que 1 était une expression non-nulle et ainsi le traduire en *
__________________
Mon blog : laurentschneider.com
Mon livre : Advanced Oracle SQL Programming
laurentschneider est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/11/2007, 10h01   #20
Membre confirmé
 
Inscription : mars 2007
Messages : 750
Détails du profil
Informations forums :
Inscription : mars 2007
Messages : 750
Points : 277
Points : 277
bon ba merci à tous pour vos réponses
farenheiit est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 12h15.


 
 
 
 
Partenaires

Hébergement Web