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

SQL Firebird Discussion :

Optimisation d'une Table / Requete


Sujet :

SQL Firebird

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 46
    Points : 26
    Points
    26
    Par défaut Optimisation d'une Table / Requete
    Bonjour,

    J'ai actuellement une table qui a le schéma suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    TYPETAUX      CHAR(1) NOT NULL
    CODEPERSONNE  VARCHAR(10) NOT NULL
    CODEPRODUIT   VARCHAR(5) NOT NULL
    TAUX          DECIMAL(15,5)
    DAT           DATE NOT NULL
    Elle Contient plusieurs millions d'enregistrements, mes SELECT toujours de la forme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT CODEPRODUIT,TYPETAUX,TAUX WHERE CODEPERSONNE = XXXX AND DAT = XXXX.
    Première question : est il recommandé de faire des SELECT sur des champs VARCHAR, la requete ne serait elle pas plus rapide si mon champ CODEPERSONNE était de type INTEGER ?

    Seconde question : les données dans cette table sont toujours ou presque lié par 2, je m'explique :

    - pour chaque jour,personne,produit j'ai 2 enregistrements, 1 avec TYPETAUX à A et B :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    A,TOTO,XR25,12.5421,'12.06.09'
    B,TOTO,XR25,18.324 ,'12.06.09'
    Je voulais savoir si je pouvais avoir une requete qui ramène 1 seul enregistrement avec les 2 valeurs de TAUX (1 avec le TYPETAUX A et l'autre B) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TOTO,XR25,12.5421,18.324,'12.06.09'
    Ou vaut il mieux créer une SECONDE TABLE alimenté par TRIGGERS sur les DELETE et INSERT de la première qui aurait ce schéma et qui me permettrai de ramener simplement 1 enregistrement avec les 2 TAUX:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CODEPERSONNE  VARCHAR(10) NOT NULL
    CODEPRODUIT   VARCHAR(5) NOT NULL
    TAUX_A        DECIMAL(15,5)
    TAUX_A        DECIMAL(15,5)
    DAT           DATE NOT NULL
    La Table d’origine n’a pas ce schéma, car je penses que niveau performance c’est mieux de faire un DELETE / INSERT ( WHERE CODEPERSONNE,CODEPRODUIT,TYPETAUX,DAT) plutôt que dans le second schéma, un SELECT Si enregistrement alors UPTDATE sinon INSERT, car en fait l’alimentation de TAUX avec TYPETAUX A ou B ne se fait pas du tout en même temps dans mon programme.

    Merci

  2. #2
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 947
    Points : 5 846
    Points
    5 846
    Par défaut
    Citation Envoyé par silmortes Voir le message
    La Table d’origine n’a pas ce schéma, car je penses que niveau performance c’est mieux de faire un DELETE / INSERT ( WHERE CODEPERSONNE,CODEPRODUIT,TYPETAUX,DAT) plutôt que dans le second schéma, un SELECT Si enregistrement alors UPTDATE sinon INSERT, car en fait l’alimentation de TAUX avec TYPETAUX A ou B ne se fait pas du tout en même temps dans mon programme.
    Je ne sais pas si c'est ce que tu recherches, mais pour ce point il y a MERGE. Si tu es sous Mysql c'est ON DUPLICATE KEY (qui est moins flexible car comme son nom l'indique, il faut s'appuyer sur une contrainte d'unicité)

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 46
    Points : 26
    Points
    26
    Par défaut
    En Effet cette Instruction est pas mal, je ne connaissais pas, j'ai trouvé egalement "UPDATE OR INSERT" dont la syntaxe me parait plus simple.

    cependant j'ai un soucis, sur UPDATE je voudrais que la requete fasse TAUX_A = TAUX_A + :NOUVELLE_VALEUR, mais il n'accepte pas cette syntaxe : Column unknown. TAUX_A.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    UPDATE OR INSERT INTO TAUX (CODEPERSONNE ,CODEPRODUIT ,DAT, TAUX_A) 
    VALUES (:CODEPERSONNE,:CODEPRODUIT,:DAT,TAUX_A + :NOUVELLE_VALEUR);

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 46
    Points : 26
    Points
    26
    Par défaut Snif Snif
    Hum personnes pour m'aider à cloturer mon petit soucis...

  5. #5
    Membre expert

    Homme Profil pro
    Consultant spécialité Firebird
    Inscrit en
    Mai 2002
    Messages
    2 342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Consultant spécialité Firebird
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Par défaut
    Citation Envoyé par silmortes Voir le message
    la requete ne serait elle pas plus rapide si mon champ CODEPERSONNE était de type INTEGER ?
    surement oui
    Citation Envoyé par silmortes Voir le message
    Je voulais savoir si je pouvais avoir une requete qui ramène 1 seul enregistrement avec les 2 valeurs de TAUX (1 avec le TYPETAUX A et l'autre B) :
    TOTO,XR25,12.5421,18.324,'12.06.09'
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    select
     CODEPERSONNE, CODEPRODUIT, 
    SUM(CASE WHEN TYPETAUX='A' THEN TAUX ELSE 0 END) TXA,  
    SUM(CASE WHEN TYPETAUX='B'  THEN TAUX ELSE 0 END) TXB,
    DAT 
    from
      MATABLE
    GROUP by
      CODEPERSONNE, CODEPRODUIT, DAT
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 46
    Points : 26
    Points
    26
    Par défaut
    Un grand merci pour cette réponse, je n'ai pas pu répondre avant j'ai eu quelques petits soucis, cependant j'ai migrer mon métadata dans cette structure :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    CODEPERSONNE  VARCHAR(10) NOT NULL
    CODEPRODUIT   VARCHAR(5) NOT NULL
    DAT           DATE NOT NULL
    TAUX_A          DECIMAL(15,5)
    TAUX_B          DECIMAL(15,5)
    j'ai donc l'utilité d'utiliser cette requete pour faire mes mises à jour :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    UPDATE OR INSERT INTO TAUX (CODEPERSONNE ,CODEPRODUIT ,DAT, TAUX_A) 
    VALUES (:CODEPERSONNE,:CODEPRODUIT,:DAT,TAUX_A + :NOUVELLE_VALEUR);
    qui me renvoi toujours l'erreur : "Column unknown. TAUX_A"

    merci.

  7. #7
    Membre expert

    Homme Profil pro
    Consultant spécialité Firebird
    Inscrit en
    Mai 2002
    Messages
    2 342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Consultant spécialité Firebird
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 46
    Points : 26
    Points
    26
    Par défaut
    Désolé, je vais passer pour un boulet, mais j'ai essayer cette fonction MERGE, mais surement à cause d'une mauvaise syntaxe, je n'ai pas réussi à la faire fonctionner.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    MERGE INTO TAUX c
      USING (SELECT * FROM TAUX WHERE (CODEPERSONNE = :CODEPERSONNE) AND (CODEPRODUIT = :CODEPRODUIT) AND (DAT = :DAT) ) cd
      ON (c.CODEPERSONNE = cd.CODEPERSONNE) AND (c.CODEPRODUIT = cd.CODEPRODUIT) AND (c.DAT = cd.DAT)
    WHEN MATCHED THEN
          UPDATE SET
          TAUX_A = TAUX_A + :NOUVELLE_VALEUR 
    WHEN NOT MATCHED THEN
          INSERT (CODEPERSONNE ,CODEPRODUIT ,DAT, TAUX_A)
          VALUES (:CODEPERSONNE ,:CODEPRODUIT ,:DAT, :TAUX_A)

  9. #9
    Membre expert

    Homme Profil pro
    Consultant spécialité Firebird
    Inscrit en
    Mai 2002
    Messages
    2 342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Consultant spécialité Firebird
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Par défaut
    c'est quoi la clé primaire de ta table ?
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

  10. #10
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 46
    Points : 26
    Points
    26
    Par défaut
    Voici la Clé primaire de ma Table :

    CODEPERSONNE ,CODEPRODUIT ,DAT

    Merci.

  11. #11
    Membre expert

    Homme Profil pro
    Consultant spécialité Firebird
    Inscrit en
    Mai 2002
    Messages
    2 342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Consultant spécialité Firebird
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Par défaut
    bon au delà du fait qu'utiliser un champ date dans une clé primaire n'est pas une bonne idée et que ton cas est un peu tordu pour utiliser INSERT OR UPDATE ou MERGE car tu cherches à mettre à jour un champ avec la valeur déjà existante dans le champ, c'est quand même faisable avec les deux.
    Ceci dit, je passerai plutot par une procédure pour cela.
    mais bon voilà :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    UPDATE OR INSERT INTO TAUX (CODEPERSONNE ,CODEPRODUIT ,DAT, TAUX_A) 
    VALUES (:CODEPERSONNE,:CODEPRODUIT,:DAT,(SELECT COALESCE((SELECT TAUX_A FROM TAUX WHERE  CODEPERSONNE=:CODEPERSONNE AND CODEPRODUIT=:CODEPRODUIT AND DAT=:DAT),0) FROM RDB$DATABASE)+ :NOUVELLE_VALEUR);
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    MERGE INTO TAUX c
      USING (SELECT :CODEPERSONNE CODEPERSONNE, :CODEPRODUIT CODEPRODUIT, :DAT DAT, :NOUVELLE_VALEUR TAUX_A FROM RDB$DATABASE) cd
      ON (c.CODEPERSONNE = cd.CODEPERSONNE) AND (c.CODEPRODUIT = cd.CODEPRODUIT) AND (c.DAT = cd.DAT)
    WHEN MATCHED THEN
          UPDATE SET
          TAUX_A = TAUX_A + cd.TAUX_A 
    WHEN NOT MATCHED THEN
          INSERT (CODEPERSONNE ,CODEPRODUIT ,DAT, TAUX_A)
          VALUES (cd.CODEPERSONNE ,cd.CODEPRODUIT ,cd.DAT, cd.TAUX_A)
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

  12. #12
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 46
    Points : 26
    Points
    26
    Par défaut
    Sinon actuellement j'ai deja une procedure stockée qui fait un SELECT sur ma clé primaire, si le SELECT ne ramène rien je fait mon INSERT sinon je fait un UPDATE.

    J'avais pensé que d'utiliser une fonction NATIVE qui gère ceci était plus performant.

    Pour la partie Tordu, elle ne l'est pas vraiment, je cherches à mettre à jour un champ avec une valeur déjà existante dans le champ, mais je sais pas si l'enregistrement est créé dans la Base à moins de faire un SELECT avant, d'ou l'utilité d'utiliser cette fonction.

    Mais ce n'est peut etre pas la Bonne solution.

    Mais concernant la clé primaire contenant une date, pourquoi n'est ce pas une bonne idées, j'ai besoins d'avoir 1 enregistrement par CODEPERSONNE ,CODEPRODUIT ,DAT...

  13. #13
    Membre expert

    Homme Profil pro
    Consultant spécialité Firebird
    Inscrit en
    Mai 2002
    Messages
    2 342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Consultant spécialité Firebird
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Par défaut
    1/ il ne faut pas confondre cclé primaire et contrainte d'unicité
    en général, une clé primaire composite, c'est pas terrible et encore moins avec des champs de type date ou time

    2/ "tordu" c'est par rapport aux fonctions INSERT OR UPDATE et MERGE

    3/ si tu en arrives là, c'est peut être (et même surement) parce que ta structure n'est pas terrible
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

  14. #14
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 46
    Points : 26
    Points
    26
    Par défaut
    Ok merci pour vos réponses, je vais refaire le point la dessus.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [10gR2] Optimisation d'une table contenant un historique
    Par Zidmann dans le forum Administration
    Réponses: 7
    Dernier message: 14/06/2013, 12h53
  2. Réponses: 1
    Dernier message: 15/05/2013, 15h03
  3. Initialiser (ou Vider ) Une Table Requete
    Par dogon dans le forum WinDev
    Réponses: 4
    Dernier message: 24/07/2007, 13h34
  4. Optimisation d'une table
    Par gregal dans le forum Langage SQL
    Réponses: 8
    Dernier message: 16/02/2007, 14h42
  5. Optimisation d'une table
    Par jexl dans le forum SQL Procédural
    Réponses: 2
    Dernier message: 15/12/2005, 13h22

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