IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage SQL Discussion :

Problème de création d'index


Sujet :

Langage SQL

  1. #21
    Membre chevronné
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Points : 1 806
    Points
    1 806
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    Sur le plan de la logique de la requête, je préfère la première mais pourrait-il y avoir une différence entre les deux sur le plan de l'utilisation des index ?
    Vu que le résultat n'est pas le même, la réponse est oui. Cependant dans les deux cas, l'idéal est d'avoir un index sur Client(Commercial,Nom). C'est juste que dans le 1er cas, on utilisera l'index en range, et dans le 2ème, on fera une lecture complète de l'index.

  2. #22
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    C'est dommage que vous n'ayez pas pris le temps d'essayer !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    CREATE TABLE CLIENT (NOM VARCHAR(8), COMMERCIAL VARCHAR(8))
     
    INSERT INTO CLIENT (NOM, COMMERCIAL)
    VALUES ('DUPONT', 'BROUARD' ),
           ('MARTIN', 'CINEPHIL'),
           ('MULLER', NULL      );
     
    CREATE TABLE ADRESSE (NOM VARCHAR(8), VILLE VARCHAR(16))
     
    INSERT INTO ADRESSE (NOM, VILLE)
    VALUES ('DUPONT', 'LYON'), 
           ('MARTIN', 'PARIS');
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
        SELECT C.NOM, A.VILLE
          FROM CLIENT  as C
     LEFT JOIN ADRESSE as A
            ON A.NOM = C.NOM
         WHERE C.COMMERCIAL = 'BROUARD'
     
    NOM      VILLE
    -------- ----------------
    DUPONT   LYON
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        SELECT C.NOM, A.VILLE
          FROM CLIENT  as C
     LEFT JOIN ADRESSE as A
            ON A.NOM = C.NOM
           AND C.COMMERCIAL = 'BROUARD'
     
    NOM      VILLE
    -------- ----------------
    DUPONT   LYON
    MARTIN   NULL
    MULLER   NULL

  3. #23
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Effectivement, je n'ai pas pris le temps mais en relisant mon message avec mes requêtes supplémentaires après l'avoir écrit, je subodorais un problème !

    Bref ! C'est le défaut de travailler avec des exemples bidons. Il est évident que je n'aurais jamais écrit la seconde requête dans un cas réel. Ni même la première car je ne ferais pas la jointure sur un nom mais sur un identifiant.

    J'espère quand même que vous avez compris le sens de mon interrogation et de mes suppositions concernant l'utilisation des index selon qu'une condition de restriction se trouve dans la condition de jointure ou dans le WHERE.

    Nous avons divergé sur le sujet initial de cette discussion, c'était juste par curiosité que je me posais ces questions.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  4. #24
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 147
    Points : 7 392
    Points
    7 392
    Billets dans le blog
    1
    Par défaut
    C'est quoi cette indentation pourrie ? j'ai dû mettre au moins 30 minutes à comprendre où était la différence entre les deux requêtes !

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    -- Requête 1 :
    SELECT C.NOM, A.VILLE
    FROM CLIENT  AS C
    LEFT OUTER JOIN ADRESSE AS A ON A.NOM = C.NOM
    WHERE C.COMMERCIAL = 'BROUARD';
     
    -- Requête 2 :
    SELECT C.NOM, A.VILLE
    FROM CLIENT  AS C
    LEFT OUTER JOIN ADRESSE AS A ON A.NOM = C.NOM AND C.COMMERCIAL =  BROUARD';
    C'est quand même plus lisible non ?

    Sinon, filtrer une autre table que la table jointe dans la clause ON, je savais même pas que c'était supporté.
    C'est standard ?

    Après mûre réflexion, ça peut avoir son utilité (je dirais même que si Oracle le supporte, je devrais pouvoir amplement simplifier des requêtes de taré que j'ai écrit) mais en revanche, c'est tout sauf lisible et évident...
    On ne jouit bien que de ce qu’on partage.

  5. #25
    Membre chevronné
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Points : 1 806
    Points
    1 806
    Par défaut
    Citation Envoyé par StringBuilder Voir le message
    Sinon, filtrer une autre table que la table jointe dans la clause ON, je savais même pas que c'était supporté.
    C'est standard ?
    Standard au sens détail de la norme SQL, je ne sais pas, mais Oracle et SQL Server le supportent.

  6. #26
    Membre confirmé Avatar de juvamine
    Profil pro
    Chef de projet MOA
    Inscrit en
    Mai 2004
    Messages
    414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Mai 2004
    Messages : 414
    Points : 502
    Points
    502
    Par défaut
    La requete 2 va générer beaucoup + de lectures logiques...pas sur que ce soit donc un gain de temps en environnement de production
    Juvamine

  7. #27
    Membre chevronné
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Points : 1 806
    Points
    1 806
    Par défaut
    À partir du moment où les 2 requêtes n'ont pas le même périmètre (la 2ème requête ramenant toute la table Client), est-il vraiment pertinent de comparer les performances des deux ?

  8. #28
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Citation Envoyé par StringBuilder Voir le message
    Sinon, filtrer une autre table que la table jointe dans la clause ON, je savais même pas que c'était supporté.
    Une jointure concerne toujours au moins deux tables.

  9. #29
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 197
    Points : 12 772
    Points
    12 772
    Par défaut
    Citation Envoyé par Waldar Voir le message
    Une jointure concerne toujours au moins deux tables.
    Ce ne serait pas plutôt:
    Une jointure concerne TOUJOURS 2 tables ?

    Je ne vois pas trop comment faire une jointure avec 3 tables.

    Tatayo.

  10. #30
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Si on est sur les mots, j'ai dit une autre bêtise, vu qu'on peut faire des auto-jointures.

    En écrivant le mot toujours j'avais en tête ce genre de jointures :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
          FROM A
    INNER JOIN B
            ON B.id = A.id
    INNER JOIN C
            ON C.col1 = B.col1
           AND C.col2 = A.col3

  11. #31
    Membre chevronné
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Points : 1 806
    Points
    1 806
    Par défaut
    Citation Envoyé par Waldar Voir le message
    Si on est sur les mots, j'ai dit une autre bêtise, vu qu'on peut faire des auto-jointures.
    On peut même faire des non-jointures !

    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT *
      FROM A 
              LEFT JOIN B
                      ON (1 = 0)

  12. #32
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 197
    Points : 12 772
    Points
    12 772
    Par défaut
    Waldar => Effectivement, dans ce cas la deuxième jointure porte sur 3 tables. J'etais resté sur une requête avec une jointure... hypothèse du mode clos, fin de semaine, tout ça...

    Tatayo.

  13. #33
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 147
    Points : 7 392
    Points
    7 392
    Billets dans le blog
    1
    Par défaut
    Non, mais ce qui me choque, c'est que l'on puisse, dans le ON filtrer un sous-ensemble de la table référante :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    select *
    from referante
    left outer join referee on referee.fk_id = referante.id and referante.champ = 'filtre';

    Ce qui se traduit littéralement par :
    Récupère-moi toutes les lignes de la table référante, ainsi que les lignes de la table référées uniquement lorsque champ champ de la table référante est égale à filtre.
    C'est à dire qu'on va faire un LEFT OUTER JOIN partiel, qui ne porte que sur un sous-ensemble de la table référante. J'aurais jamais imaginé que ça puisse marcher !

    C'est à dire, en d'autres termes "ramène-moi tous les clients, ainsi que les adresses de seulement ceux qui ont 20 ans".
    Habituellement, c'est plutôt "ramène-moi tous les clients, ainsi que les adresses de seulement ceux qui habitent Lyon", ce qui est loin d'être la même chose.

    Jusqu'à présent, j'aurai écrit ce truc ignoble, sous Oracle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    select *
    from client
    left outer join adresse on adresse.client_id = decode(client.age, 20, client.id, null);
    On ne jouit bien que de ce qu’on partage.

  14. #34
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 197
    Points : 12 772
    Points
    12 772
    Par défaut
    Je ne trouve pas que ce soit si choquant (à part dans cet exemple !), et d'ailleuirs j'ai un exemple concret:
    Dans une application de réassort, je traite des articles "centralisés", et des articles direct fournisseur.
    Comme le fournisseur des produits centralisés est caché aux utilisateur, je ne dois afficher le fournisseur que pour les articles "direct fournisseur":
    En simplifiant la requête
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    select article.reference,fournisseur.code
    from article
    left outer join frn_art on frn_art.idart = article.id and article.centralise = faux

    literralement: récupère moi les articles, et le fournisseur uniquement pour les produits non centralisés.

    Tatayo.

Discussions similaires

  1. Réponses: 2
    Dernier message: 24/08/2012, 14h20
  2. Problème de création d'index
    Par bivancha dans le forum SQL
    Réponses: 5
    Dernier message: 23/01/2012, 16h18
  3. [Debutant]Problème de création d'une vue indexée
    Par Le Pharaon dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 15/11/2006, 12h50
  4. Problème de création de fenêtre
    Par tomateauketchup dans le forum DirectX
    Réponses: 1
    Dernier message: 08/06/2003, 19h42
  5. [Rave Report] problème de création dynamique
    Par Nivux dans le forum Rave
    Réponses: 2
    Dernier message: 24/05/2003, 00h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo