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

 Oracle Discussion :

Utilisation des index dans une requête


Sujet :

Oracle

  1. #41
    Membre éprouvé
    Inscrit en
    Avril 2006
    Messages
    1 024
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 1 024
    Points : 1 294
    Points
    1 294
    Par défaut
    c'est le montant du deuxième curseur qui fait le lien
    Oui mais comment ? par quelle requête ? comment est remplie ta variable code_plage ?

    C'est peut être bien là qu'un index est manquant... parceque mon petit doigt me dit qu'une colonne contenant des montants n'est pas naturellement celle qui me viendrait à l'idée d'indexer... sans parler de la perplexité que j'ai sur une conception qui prévoit de faire le lien sur un ce genre de champ!

  2. #42
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2010
    Messages
    56
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2010
    Messages : 56
    Points : 26
    Points
    26
    Par défaut
    vous livrez les informations au compte-goute, c'est un peu pénible
    quelle partie vous semble floue?je croyais pourtant avoir été claire.si ya une partie qui semble floue,dite lequel,je me ferai le plaisir d'être plus claire.mais je vais essayer votre proposition.
    merci

  3. #43
    Membre éprouvé
    Inscrit en
    Avril 2006
    Messages
    1 024
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 1 024
    Points : 1 294
    Points
    1 294
    Par défaut
    par exemple, le dernier curseur il vient d'apparaitre, et il reste encore un mystère: comment donc est valorisée la variable code_plage ?!

  4. #44
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2010
    Messages
    56
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2010
    Messages : 56
    Points : 26
    Points
    26
    Par défaut
    Oui mais comment ? par quelle requête ? comment est remplie ta variable code_plage ?
    en faite ma variable code_plage est un champ d'une forms qui est remplie dès qu'on appuie sur le bouton tabulation(un évènement KEY-NEXT-ITEM) par le montant correspondant à la plage
    donc je remplis le champ de la forms code_plage.et c'est avec ce même code_plage là que je fais le lien avec la table produits pour avoir le libellé correspondant. en faisant ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    CURSOR C IS
        SELECT libellé,prix_unitaire
      	FROM produits
        WHERE code_produit=code_plage;
    puis dans la table produit,les valeurs sont figés et enregistrées à l'avance.
    c'est claire now?

  5. #45
    Membre éprouvé
    Inscrit en
    Avril 2006
    Messages
    1 024
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 1 024
    Points : 1 294
    Points
    1 294
    Par défaut
    Donc si je comprend bien au final, ça revient à comparer le champ "montant" à un champ "code" je sais pas si c'est un pb de nommage ou de conception, mais ça fait drole lol

    Donc, a priori je maintient ce que j'ai dit plus haut: pb d'index sur code_produit ou pb de conversion implicite varchar -> number.

  6. #46
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2010
    Messages
    56
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2010
    Messages : 56
    Points : 26
    Points
    26
    Par défaut
    Donc si je comprend bien au final, ça revient à comparer le champ "montant" à un champ "code" je sais pas si c'est un pb de nommage
    voici le contenu de ma table produit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    CODE_PRODUIT LIBELLE     PRIX_UNITAIRE  CODE_TYPE
    ------------ ------------------------------ -------- -----
            50       50 F                       50              1
           100     100 F                     100             2
            200    200 F                      200            3
    Ainsi dès que l'utilisateur rentre la plage le starting_id et le ending_id,je récupère le montant corespondant à cette plage comme ceci:
    ,
    que je compare ensuite :code_plage avec code_produit qui est pré-enregistré afin de pouvoir avoir le libellé.je crois que tu as raison,cest un problème de nommage surement.
    ca va un peu plus maintenant?

  7. #47
    Membre éprouvé
    Inscrit en
    Avril 2006
    Messages
    1 024
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 1 024
    Points : 1 294
    Points
    1 294
    Par défaut
    Ah oui alors si y'a que 3 lignes dans la table produit, laisse tomber mes hypothèses...

    C'est quoi en gros le volume de la table activation ? (nb de ligne, largeur des colonnes)

    EDIT: question subsidiaire dans la plage rentrée, ça représente combien de ligne en gros ? car si c'est de l'ordre de la dizaine, c'est clair qu'il ne prend pas l'index, faut juste comprendre pourquoi...

  8. #48
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2010
    Messages
    56
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2010
    Messages : 56
    Points : 26
    Points
    26
    Par défaut
    EDIT: question subsidiaire dans la plage rentrée, ça représente combien de ligne en gros ? car si c'est de l'ordre de la dizaine, c'est clair qu'il ne prend pas l'index, faut juste comprendre pourquoi...
    tu veux parler de la table num_serie_montant au lieu d'activation.
    j'ai chargé 3000000 de lignes.

  9. #49
    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
    Je vous ai mis une requête qui devrait tout faire, elle se situe à la page précédente.

    Merci d'être attentif aux solutions qu'on vous apporte

  10. #50
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2010
    Messages
    56
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2010
    Messages : 56
    Points : 26
    Points
    26
    Par défaut
    oui!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    SELECT case count(DISTINCT prd.code_produit)
             when 1 then 'OK'
             else 'Plusieurs produits sur la plage saisie'
           end AS statut,
           case count(DISTINCT prd.code_produit)
             when 1 then min(prd.libellé)
           end AS libellé,
           case count(DISTINCT prd.code_produit)
             when 1 then min(prd.prix_unitaire)
           end AS prix_unitaire
      INTO :statut, :libellé, :prix_unitaire
      FROM activation.num_serie_montant nsm
           INNER JOIN produits prd
             ON prd.code_produit = nsm.montant
     WHERE to_number(nsm.num_serie) BETWEEN :starting_id AND :ending_id;
    en fait je suis entrain d'essayer de la comprendre afin de l'adapter à mon code.je vous tiens informer.
    Merci

  11. #51
    Membre éprouvé
    Inscrit en
    Avril 2006
    Messages
    1 024
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 1 024
    Points : 1 294
    Points
    1 294
    Par défaut
    Ah et aussi, je me souvient plus dans quelle version c'est par défaut et dans quelle version il faut le mettre, mais il faut que le paramètre oracle QUERY_REWRITE_ENABLED soit à "true" si on veut que les index sur fonction fonctionnent... (ici sur le to_number)

    Parceque si ta plage d'entrée fait que tu ne couvre que quelques lignes de ta table activation, alors la réponse devrait être instantanée, sinon c'est que l'index n'est pas utilisée.

    Ensuite, j'ai quelques doutes sur la pertinance de la méthode en pour le résultat que tu veux obtenir. Si au final, c'est pour bidouiller une table à 3 lignes, est-ce qu'il ne vaudrait pas mieux faire une requête qui part d'elle, et qui filtre sur la grosse par des EXISTS ?...

  12. #52
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2010
    Messages
    56
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2010
    Messages : 56
    Points : 26
    Points
    26
    Par défaut
    Ah et aussi, je me souvient plus dans quelle version c'est par défaut et dans quelle version il faut le mettre, mais il faut que le paramètre oracle QUERY_REWRITE_ENABLED soit à "true" si on veut que les index sur fonction fonctionnent... (ici sur le to_number)

    Parceque si ta plage d'entrée fait que tu ne couvre que quelques lignes de ta table activation, alors la réponse devrait être instantanée, sinon c'est que l'index n'est pas utilisée.

    Ensuite, j'ai quelques doutes sur la pertinance de la méthode en pour le résultat que tu veux obtenir. Si au final, c'est pour bidouiller une table à 3 lignes, est-ce qu'il ne vaudrait pas mieux faire une requête qui part d'elle, et qui filtre sur la grosse par des EXISTS ?...
    j'ai plus le to_number,j'ai modifier mon schéma.j'ai mis le type number(9) à la place du varchar2.
    pour ta proposition,elle me semble bonne,mais comment?

  13. #53
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2010
    Messages
    56
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2010
    Messages : 56
    Points : 26
    Points
    26
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    SELECT case count(DISTINCT prd.code_produit)
             when 1 then 'OK'
             else 'Plusieurs produits sur la plage saisie'
           end AS statut,
           case count(DISTINCT prd.code_produit)
             when 1 then min(prd.libellé)
           end AS libellé,
           case count(DISTINCT prd.code_produit)
             when 1 then min(prd.prix_unitaire)
           end AS prix_unitaire
      INTO :statut, :libellé, :prix_unitaire
      FROM activation.num_serie_montant nsm
           INNER JOIN produits prd
             ON prd.code_produit = nsm.montant
     WHERE to_number(nsm.num_serie) BETWEEN :starting_id AND :ending_id;
    j'arrive pas à comprendre la requête.excusez moi mais pourquoi vous faites le count distinct sur le code_produit au lieu du montant de la table num_serie_montant?
    merci d'être patient avec moi

  14. #54
    Membre éprouvé
    Inscrit en
    Avril 2006
    Messages
    1 024
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 1 024
    Points : 1 294
    Points
    1 294
    Par défaut
    Citation Envoyé par sanouphil Voir le message
    j'ai plus le to_number,j'ai modifier mon schéma.j'ai mis le type number(9) à la place du varchar2.
    pour ta proposition,elle me semble bonne,mais comment?
    Ah ok, ben laisse tomber alors, si y'a plus le to_number, ça ne pose plus de problème, mais as-tu bien pensé à refaire l'index du coup ?

    Pour acter que le pb vient bien de ce curseur, tu peux t'amuser à jouer la requête toute seule dans un sqlplus, ça te validera (ou pas) que c'est bien elle qui rame.

  15. #55
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2010
    Messages
    56
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2010
    Messages : 56
    Points : 26
    Points
    26
    Par défaut
    en supprimant les to_number et les curseurs et en créant un index sur num_serie de la table num_serie_montant,je suis passé de 20s à 10s pour le parcours de 3000000 lignes.mais je crois que je peux faire mieux.merci tout même à vous tous!
    j'ai essayé la solution de waldar,mais je ne m'en sort pas!
    mais dis moi remi4444 penses tu que j'ai besoin d'un curseur pour la table produits?

  16. #56
    Membre éprouvé
    Inscrit en
    Avril 2006
    Messages
    1 024
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 1 024
    Points : 1 294
    Points
    1 294
    Par défaut
    Non, tu n'as pas besoin de curseur, mais dans la mesure ou elle fait 3 lignes, c'est pas ça qui joue sur les perfs.

    Le fait de passer 20 à 10 est comme préveu la division par 2 liée au fait que tu ne fais plus qu'un seul parcours de table au lieu de 2.

    Si j'ai bien compris, le noeud du problème est que tu dois parcourir potentiellement beaucoup de lignes juste pour savoir si il y a ou pas des valeurs distinctes de ton champ montant. Et si j'ai toujours bien compris, tu t'en fiche de savoir le comptage exact, c'est juste la récupération d'une occurence du champ avec vérification qu'il n'y en a pas d'autres.

    Au final, l'info qui t'intéresse se trouve dans la table produits, la grosse table num_serie_montant ne servant que de filtrage, de selection du bon produit.

    Donc...

    La démarche devrait être de partir de cette table produit comme table maitre et de filtrer par la table num_serie_montant à l'aide l'instruction dédiée au filtrage qui est EXISTS. Cette instruction a l'ennorme avantage pour toi de s'arrêter à la première occurence trouvée, ce qui économise moult accès disques.

    De plus, il pourrait être interressant de faire un index sur la table num_serie_montant qui couvre tes 2 champs. Si ta table ne comporte elle même que ces 2 champs, alors tu pourras encore améliorer plus tard en la déclarant "organization index" ce qui veux dire que la table n'est plus qu'un index, ce qui va diviser encore par 2 le volume pris et éventuellement tes accès disques.

    pour finir, plutot que de faire un comptage de vérif puis une selection, autant faire tout en une fois, prendre le max et le min et comparer à la fin si c'est la meme chose, ce qui signifiera l'unicité.

    Ce qui se traduit par un truc du style:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    create unique index idx_mont_ser on num_serie_montant ( montant,numero_serie)
     
    select max(p.code_produit) code_produit,min(p.code_produit) verif 
     into :code_produit, :verif from  produit p 
    where exists
     (select 1 from num_serie_montant n 
        where n.MONTANT = p.code_produit 
        and n.numero_serie between :debut and :fin)

  17. #57
    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 remi4444 Voir le message
    Au final, l'info qui t'intéresse se trouve dans la table produits, la grosse table num_serie_montant ne servant que de filtrage, de selection du bon produit.
    Il faut que ce montant ne se trouve qu'une et une seule fois dans la table num_serie_montant sur la plage donnée.

  18. #58
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2010
    Messages
    56
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2010
    Messages : 56
    Points : 26
    Points
    26
    Par défaut
    slt les amis!!
    je crois que je comprends un peu votre idée.Mais le problème est que la requête associée à la récupération du libellé est derrière un autre évènement post-change et est comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    DECLARE
        begin
     
        	  SELECT LIB_PRODUIT,prix_unitaire_ord into :lib_carte,:prix_unitaire
          	FROM produits
            WHERE CODE_PRODUIT=:CARTE_ACTIVATION.CODE_CARTE;
     
      	:CARTE_ACTIVATION.SHOP_ID:=:activation.shop_id;
      	:CARTE_ACTIVATION.LIB_CARTE:=:LIB_CARTE;
     
    end;
    alors que la requête que vous m'avez proposée est derrière l'évènement KEY-NEXT-ITEM.ce qui rend cette proposition problématique à appliquer.
    malheureusement.sinon elle a l'air bonne votre idée

  19. #59
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2010
    Messages
    56
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2010
    Messages : 56
    Points : 26
    Points
    26
    Par défaut
    excusez moi pour cette précision que j'avais oublié de donner
    a récupération du libellé est derrière un autre évènement post-change
    .
    Merci d'être indulgent avec moi.

  20. #60
    Membre éprouvé
    Inscrit en
    Avril 2006
    Messages
    1 024
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 1 024
    Points : 1 294
    Points
    1 294
    Par défaut
    En dehors du fait que les infos sont données au compte goute je ne crois pas que cette requêtes pose un particulier problème puisqu'elle ne fait appel qu'à une table de 3 lignes...

    J'insiste sur le fait qu'il faudrait que tu testes ta requete du curseur de manière complétement indépendante du reste pour valider le fait que le pb vient bien de là.

+ Répondre à la discussion
Cette discussion est résolue.
Page 3 sur 4 PremièrePremière 1234 DernièreDernière

Discussions similaires

  1. [MySQL] Utilisation des alias dans une requête
    Par methodman225 dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 29/09/2008, 12h55
  2. Utilisation des parametres dans une requéte
    Par ange_dragon dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 13/06/2007, 09h32
  3. Utiliser des "SI" dans une requête access ?
    Par shaenwe dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 14/03/2007, 12h25
  4. Comment utiliser des variables dans une requête SQL ?
    Par Ragnarok85 dans le forum Requêtes et SQL.
    Réponses: 10
    Dernier message: 12/02/2007, 16h23

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