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 PHP Discussion :

[Tableaux] Recherche clé dans tableau multi-dimensionnel


Sujet :

Langage PHP

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2002
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2002
    Messages : 37
    Points : 26
    Points
    26
    Par défaut [Tableaux] Recherche clé dans tableau multi-dimensionnel
    Bonjour

    Je cherche une fonction permettant de retourner toutes les clés correspondant à une valeur dans un tableau multi-dimensionnel.

    Exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    $tableau[0]['age']=19;
    $tableau[0]['prenom']="Pierre";
     
    $tableau[1]['age']=21;
    $tableau[1]['prenom']="Paul";
     
    $tableau[2]['age']=21;
    $tableau[2]['prenom']="Jacques";
    je voudrai connaitre les clés de mon tableau des personnes ayant 21 ans..

    merci de votre aide!

  2. #2
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2007
    Messages
    748
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 748
    Points : 1 022
    Points
    1 022
    Par défaut
    bon, pour moi, qui suis un invétérer de la boucle for
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     
    $tableau[0]['age']=19;
    $tableau[0]['prenom']="Pierre";
     
    $tableau[1]['age']=21;
    $tableau[1]['prenom']="Paul";
     
    $tableau[2]['age']=21;
    $tableau[2]['prenom']="Jacques";
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    $age =21;
     
    for ($i=0; $i< count($tableau) ; $i++ ){
     
    if ($tableau[$i]["age"]==$age){
     
    echo $tableau[$i]["prenom"]." à :".$age."<br />";
     
     
    }
    }
    c'est un bon exemple, de ce que l'on doit savoir faire, pour récupérer des données, d'un fichier ou d'une base de données.


    Il faut cependant pousser la réflexion, c 'est à dire :
    pourquoi utiliser le tableau multi dimentionnel dans le sens $tableau[0]['age'] et non, dans le sens $tableau['age'][0]


    Bien que la réponse tombe sous le sens, si tu ne la pas comprise, continu sur la voie de l'apprentissage de choses simples,
    comme pour cette question.


    bon courage

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2002
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2002
    Messages : 37
    Points : 26
    Points
    26
    Par défaut
    Merci pour ta réponse Ascito

    mais j'aurai du préciser "sans parcourir les valeurs de mon tableau" car il peut contenir au moins 10000 enregistrements et la boucle s'avère un peu longue à l'exécution... je pensais plus à une fonction "native" du genre array_search mais étendue aux tableaux mutlidimensionnels!

    par contre je suis un invétéré des tableaux multiples mais je n'avais jamais envisagé de mettre le paramètre comme clé ($tableau['age'][0], $tableau['prenom'][0] ...) Cela n'est-il pas plus lourd avec beaucoup d'enregistrements ?

  4. #4
    Membre expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 46

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Points : 3 344
    Points
    3 344
    Par défaut
    Tu n'as je pense pas d'autre solution que de parcourir ton tableau ! Et quand bien même une fonction ferait exactement ce que tu souhaites, elle parcourerait elle aussi ton tableau

    Par contre, plutôt qu'un for, j'utiliserais personnellement plutôt un foreach.

    Une dernière piste : n'est-il pas possible de filtrer tes données lors de l'initialisation du tableau ? Comment récupères-tu ces informations ?

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2002
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2002
    Messages : 37
    Points : 26
    Points
    26
    Par défaut
    Ok merci Eusebe

    je récupère ces données à partir d'une table MySQL. L'exemple était vraiment à titre d'exemple En réalité il s'agit d'une gestion budgétaire. Je récupère toutes mes lignes de budgets dans un tableau afin de l'envoyer vers mon moteur de templates (smarty).

    Donc je procede comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    //Parcours des lignes de mon budget
    while($data_lignes_budgets = mysql_fetch_array($res_lignes_budgets)) {
         $tab_lignes_budgets[$data_lignes_budgets['ID']]['code'] = $data_lignes_budgets['code'];
         $tab_lignes_budgets[$data_lignes_budgets['ID']]['quantite'] = $data_lignes_budgets['quantite'];
         $tab_lignes_budgets[$data_lignes_budgets['ID']]['prix_unitaire'] = $data_lignes_budgets['prix_unitaire'];
         $tab_lignes_budgets[$data_lignes_budgets['ID']]['montant'] = $data_lignes_budgets['montant'];
         //ETC...
     
    }
    ensuite j'ai besoin d'afficher pour chaque ligne de mon budget le montant correspondant au meme poste (code) d'un autre budget dit "de comparaison".
    Donc je pensais faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    $sql = "SELECT code, montant FROM t_lignes_budgets WHERE id_budget = ".$id_budget_comparaison." AND montant IS NOT NULL";
    $res = mysql_query($sql);
    while($data_budget_comparaison = mysql_fetch_array($res)) {
         $id_ligne_budget = retourne_keys($tab_lignes_budgets,$data_budget_comparaison['code']);
    //c'est ici que je veux récuperer l'ID du tableau $tab_lignes_budgets 
    //dont le code correspond à celui de mon resultat... 
    //d'ou l'objet de la discussion!
     
          $tab_lignes_budgets[$id_ligne_budget]['montant_comparaison'] = $data_budget_comparaison['montant'];
    }
    A savoir que le poste (code) n'est pas forcement unique, il peut y avoir des doublons donc plusieurs ID par code...

  6. #6
    Membre expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 46

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Points : 3 344
    Points
    3 344
    Par défaut
    D'accord, Et comment tu trouves l'identifiant du budget de comparaison ?
    Et quelle est la requête qui te permet de récupérer tes lignes de budget ?

    Parce que le plus efficace dans ton cas, ce serait de faire une seule requête sql qui permette de récupérer directement les lignes budgets et les montants des budgets de comparaison.

    Ca limitera à la fois la charge de ton serveur web (moins de boucles en php) et celle de ton serveur de base de données (une seule requête plutôt que 2 ? 50 ?)

  7. #7
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 249
    Points : 1 565
    Points
    1 565
    Par défaut
    une autre solution, si tu as besoin de toutes les données par ailleurs, est d'ajouter le test dans la boucle de récupération de données.
    Du coup en sortie de boucle tu auras 2 tableaux :
    * Celui contenant toutes les données
    * Celui contenant les données correspondant au critere souhaité (si le critere est deja connu)

    Tu évites ainsi un 2eme parcours du tableau.

    Apres évidemment, comme le dit Eusebe, tout faire en SQL c'est mieux !

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2002
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2002
    Messages : 37
    Points : 26
    Points
    26
    Par défaut
    Alors mes tables ressemblent à ceci :

    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
    16
    17
    18
    19
    20
    21
    22
    //Table des budgets
     
    t_budgets {
    	- id_budget // clé primaire
    	- id_programme // identifiant du programme associé, plusieurs budgets par programme
    	- libelle
    	- ...
    	- comparaison // bit (0|1) determine le budget de comparaison unique par programme
     
    }
     
    //Table lignes budgetaires
     
    t_lignes_budgets {
    	- id_ligne_budget // clé primaire
    	- id_budget // budget associé
    	- code
    	- quantite
    	- prix_unitaire
    	- montant
    	- ...
    }
    Et mes requetes :

    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
    16
    17
     
    //je recupere l'identifiant du budget a afficher par un $_GET
    //Recherche des donnees du budget
    $select_budget = "SELECT * FROM t_budgets WHERE id_budget = ".$_GET['id_budget'];
    $res_budget = mysql_query($select_budget);
    $data_budget = mysql_fetch_array($res_budget);
     
    //Recherche de l'identifiant du budget de comparaison
    $select_id_compare = "SELECT id_budget FROM t_budgets WHERE id_programme = ".$data_budget['id_programme']." AND comparaison = 1";
    $res_id_compare = mysql_query($select_id_compare);
    if(mysql_num_rows($res_id_compare) == 1) { //Test si le budget de comparaison existe
    	$compare = true;
    	$data_id_compare = mysql_fetch_array($res_id_compare);
    	$id_budget_comparaison = $data_id_compare['id_budget'];
    }
    else
    	$compare = false;
    Puis je recherche les lignes budgetaires

    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    $select_lignes_budget = "SELECT * FROM t_lignes_budgets WHERE id_budget = ".$_GET['id_budget'];
    $res_lignes_budget = mysql_query($select_lignes_budget);
     
    //Parcours des lignes de mon budget
    while($data_lignes_budgets = mysql_fetch_array($res_lignes_budgets)) {
         $tab_lignes_budgets[$data_lignes_budgets['ID']]['code'] = $data_lignes_budgets['code'];
         $tab_lignes_budgets[$data_lignes_budgets['ID']]['quantite'] = $data_lignes_budgets['quantite'];
         $tab_lignes_budgets[$data_lignes_budgets['ID']]['prix_unitaire'] = $data_lignes_budgets['prix_unitaire'];
         $tab_lignes_budgets[$data_lignes_budgets['ID']]['montant'] = $data_lignes_budgets['montant'];
         //ETC...
     
    }
     
    if($compare) {
         //Recherche des donnees du budget de comparaison
         $sql = "SELECT code, montant FROM t_lignes_budgets WHERE id_budget = ".$id_budget_comparaison." AND montant IS NOT NULL";
         $res = mysql_query($sql);
         while($data_budget_comparaison = mysql_fetch_array($res)) {
              $id_ligne_budget = retourne_keys($tab_lignes_budgets,$data_budget_comparaison['code']);
              //c'est ici que je veux récuperer l'ID du tableau $tab_lignes_budgets 
              //dont le code correspond à celui de mon resultat... 
              //d'ou l'objet de la discussion!
     
               $tab_lignes_budgets[$id_ligne_budget]['montant_comparaison'] = $data_budget_comparaison['montant'];
         }
    }
    Je fais ça "instinctivement" n'ayant pas de grandes notions en SQL mais s'il y a moyen d'optimiser tout ça je suis preneur!

    merci!

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2002
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2002
    Messages : 37
    Points : 26
    Points
    26
    Par défaut
    Citation Envoyé par Fladnag Voir le message
    une autre solution, si tu as besoin de toutes les données par ailleurs, est d'ajouter le test dans la boucle de récupération de données.
    Du coup en sortie de boucle tu auras 2 tableaux :
    * Celui contenant toutes les données
    * Celui contenant les données correspondant au critere souhaité (si le critere est deja connu)

    Tu évites ainsi un 2eme parcours du tableau.

    Apres évidemment, comme le dit Eusebe, tout faire en SQL c'est mieux !
    Je ne sais pas si j'ai bien saisi ta proposition, mais s'il s'agit de faire une requete pendant le parcours de mes résultats pour rechercher le montant "comparé" je l'ai deja testé et cela alourdi considérablement l'exécution du script! Mais j'ai peut être mal compris..?

  10. #10
    Membre expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 46

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Points : 3 344
    Points
    3 344
    Par défaut
    Tu peux faire une requête comme :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT bl.code,
        bl.quantite,
        bl.montant,
        cl.montant montant_compare
    FROM t_budgets b
        JOIN t_lignes_budgets bl ON b.id_budget = bl.id_budget
        LEFT OUTER JOIN t_budgets c ON c.id_programme = b.id_programme AND c.comparaison = 1
        LEFT OUTER JOIN t_lignes_budgets cl ON c.id_budget = cl.id_budget AND cl.montant IS NOT NULL AND bl.code = cl.code
    WHERE b.id_budget = ".$_GET['id_budget']

  11. #11
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 249
    Points : 1 565
    Points
    1 565
    Par défaut
    Citation Envoyé par Maheu Voir le message
    Je ne sais pas si j'ai bien saisi ta proposition, mais s'il s'agit de faire une requete pendant le parcours de mes résultats pour rechercher le montant "comparé" je l'ai deja testé et cela alourdi considérablement l'exécution du script! Mais j'ai peut être mal compris..?
    Nan, tu execute ta 1ere requete pour récuperer le budget de comparaison. Tu obtient donc toutes les infos pour "filtrer" ton 2eme tableau.

    Puis, pour la 2eme requete tu fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $tableauFiltre=array();
    while(...) {
      // remplissage du tableau comme avant
      ...
      // construction d'un 2eme tableau "filtré" 
      if ($data['montant'] > $montantBudgetComparaison) {
        $tableauFiltre[$data['ID']]['montant']=$data['montant'];
        $tableauFiltre[$data['ID']]['...']=...
        $tableauFiltre[$data['ID']]['...']=...
        $tableauFiltre[$data['ID']]['...']=...
      }
    }
    Petit conseil aussi sans rentrer dans le détail des requetes SQL au dessus :

    si tu remplaces mysql_fetch_array par mysql_fetch_assoc, les codes suivants sont équivalents :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $tab_lignes_budgets[$data_lignes_budgets['ID']]['code'] = $data_lignes_budgets['code'];
    $tab_lignes_budgets[$data_lignes_budgets['ID']]['quantite'] = $data_lignes_budgets['quantite'];
    $tab_lignes_budgets[$data_lignes_budgets['ID']]['prix_unitaire'] = $data_lignes_budgets['prix_unitaire'];
    $tab_lignes_budgets[$data_lignes_budgets['ID']]['montant'] = $data_lignes_budgets['montant'];
    ...
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $tab_lignes_budgets[$data_lignes_budgets['ID']] = $data_lignes_budgets;
    Le 2eme code est juste beaucoup plus court ^^

  12. #12
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2002
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2002
    Messages : 37
    Points : 26
    Points
    26
    Par défaut
    Merci Eusebe pour ta requete. J'ai compris le principe seulement elle fait exploser toutes mes ressources
    A noter qu'il y a ~750 records dans la table t_budgets et ~730 000 dans la table t_lignes_budgets ... mon serveur n'a pas trop aimé

    @Fladnag : merci pour l'astuce du fetch_assoc! par contre je n'ai pas compris pourquoi la condition if ($data['montant'] > $montantBudgetComparaison) ...
    D'ou vient le $montantBudgetComparaison ?

    Sinon j'ai trouvé une soluce qui consiste à placer la valeur du champ 'code' en clé de mon tableau. En cas de doublon je la concatène avec un incrément ($code.0, $code.1 ...) ce qui me va puisque je n'ai pas besoin de comparer les codes "doublons"... mais ça reste de la bricole et contraignant pour le système!

    je vais creuser du côté d'une requête unique et moins gourmande!

    merci

  13. #13
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 249
    Points : 1 565
    Points
    1 565
    Par défaut
    ben $montantComparaison ca vient de la 1ere requete, ou autre. Là c'est fonctionnel, pas technique ;o)
    Ca peut etre un tableau indexé sur l'ID du budget ou autre, je sais pas, c'est le meme if (ou l'equivalent d'une clause where existante) que tu as ailleurs pour faire la comparaison avec un autre budget.

  14. #14
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2007
    Messages
    748
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 748
    Points : 1 022
    Points
    1 022
    Par défaut
    sans être totalement convaincu, je ne me sert pas de id_programme alors que suppose qu'il sagit d'une clé étrangère

    sql structure de la base
    CREATE TABLE `t_budgets` (
    `id_budget` int(11) NOT NULL auto_increment,
    `id_programme` varchar(100) NOT NULL,
    `libelle` varchar(100) NOT NULL,
    `comparaison` varchar(100) NOT NULL,
    PRIMARY KEY (`id_budget`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;

    --
    -- Contenu de la table `t_budgets`
    --

    INSERT INTO `t_budgets` (`id_budget`, `id_programme`, `libelle`, `comparaison`) VALUES
    (0, '105', 'THTH', '0'),
    (1, '100', 'TOTO', '1'),
    (2, '101', 'TATA', '1'),
    (3, '102', 'TUTU', '1');

    -- --------------------------------------------------------

    --
    -- Structure de la table `t_lignes_budgets`
    --

    CREATE TABLE `t_lignes_budgets` (
    `id_ligne_budget` int(11) NOT NULL auto_increment,
    `id_budget` int(100) NOT NULL,
    `code` varchar(100) NOT NULL,
    `quantite` varchar(100) NOT NULL,
    `prix_unitaire` varchar(100) NOT NULL,
    `montant` varchar(100) default NULL,
    PRIMARY KEY (`id_ligne_budget`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;

    --
    -- Contenu de la table `t_lignes_budgets`
    --

    INSERT INTO `t_lignes_budgets` (`id_ligne_budget`, `id_budget`, `code`, `quantite`, `prix_unitaire`, `montant`) VALUES
    (1, 1, 'A1', '34', '57', '800'),
    (2, 1, 'A2', '23', '65', '705'),
    (4, 1, 'A3', '23', '65', NULL);


    requete

    SELECT b.code,b.montant FROM t_budgets as a,t_lignes_budgets as b WHERE a.comparaison=1 AND a.id_budget=1 and a.id_budget =b.id_budget AND b.montant IS NOT NULL

    C'est une requête super maniable, en terme de jointures, je pense que très rapidement tu devrais arriver à faire des choses complexe avec.

    as : permet de donner des alias aux noms des tables
    FROM t_budgets as a,t_lignes_budgets as b : jointure
    a.id_budget=1 : $_GET ['id_budjet']
    a.id_budget =b.id_budget empêche les produits cartésiens



    a ++

  15. #15
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2002
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2002
    Messages : 37
    Points : 26
    Points
    26
    Par défaut
    Merci Ascito mais tu as du interpréter un peu vite mon probleme.

    J'ai besoin d'une auto-jointure (si ça se dit!) entre les budgets pour afficher en parallèle les montants des lignes d'un budget donné et ceux des lignes du budget de comparaison du même programme.

    La requête de Eusebe est parfaite mais malheureusement beaucoup trop longue à exécuter (plantage systematique sur ma config), à moins que ce soit ma structure de BDD qui ne soit pas optimisée... ce qui est fort probable!

  16. #16
    Membre expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 46

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Points : 3 344
    Points
    3 344
    Par défaut
    Citation Envoyé par Maheu Voir le message
    Merci Ascito mais tu as du interpréter un peu vite mon probleme.

    J'ai besoin d'une auto-jointure (si ça se dit!) entre les budgets pour afficher en parallèle les montants des lignes d'un budget donné et ceux des lignes du budget de comparaison du même programme.

    La requête de Eusebe est parfaite mais malheureusement beaucoup trop longue à exécuter (plantage systematique sur ma config), à moins que ce soit ma structure de BDD qui ne soit pas optimisée... ce qui est fort probable!
    Qu'est-ce que tu as comme index dans ta base (et est-ce que tu peux en créer ?) ?

  17. #17
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2002
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2002
    Messages : 37
    Points : 26
    Points
    26
    Par défaut
    Sur les tables mises en oeuvre ici mes index sont :

    t_programmes :
    - id_programme (int(11)) : PRIMARY
    - nom (varchar(255)) : INDEX

    t_budgets :
    - id_budget (int(11)) : PRIMARY
    - nom (varchar(255)) : INDEX

    t_lignes_budgets :
    - id_ligne_budget (int(11)) : PRIMARY

    c'est assez primaire!

    Mais je peux en créer à profusion, l'appli n'est pas en production.

  18. #18
    Membre expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 46

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Points : 3 344
    Points
    3 344
    Par défaut
    Ajoutes en déjà au moins un sur t_lignes_budgets.id_budget, ça devrait déjà aller mieux pour la requête que je t'ai donnée...

  19. #19
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2002
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2002
    Messages : 37
    Points : 26
    Points
    26
    Par défaut
    ok ... je viens de découvrir la puissance des Index! on a un peu divergé par rapport au sujet initial mais au final j'ai appris beaucoup plus de choses

    j'ai ajouté des index sur t_budgets.id_programme, t_lignes_budgets.id_budget, t_lignes_budgets.code .. la différence est radicale!

    merci encore Eusebe! you're simply the best

  20. #20
    Membre expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 46

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Points : 3 344
    Points
    3 344
    Par défaut
    Attention quand même à ne pas ajouter des index inutiles : les index accélèrent les requêtes en lecture mais ralentissent l'écriture.

    Pour savoir quels index sont utilisés, tu peux te servir de l'instruction EXPLAIN :
    http://dev.mysql.com/doc/refman/5.0/fr/explain.html

    Enfin, n'hésites pas à tester d'autres formes de requêtes qui font la même chose, mais en utilisant un autre plan d'exécution. Par exemple pour ton cas, tu pourrais aussi faire :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SELECT bl.code,
        bl.quantite,
        bl.montant,
        (SELECT cl.montant
            FROM t_budgets c
            JOIN t_lignes_budgets cl ON c.id_budget = cl.id_budget
            WHERE c.id_programme = b.id_programme
                AND c.comparaison = 1
                AND cl.montant IS NOT NULL
                AND bl.code = cl.code) montant_compare
    FROM t_budgets b
        JOIN t_lignes_budgets bl ON b.id_budget = bl.id_budget
    WHERE b.id_budget = xxx

    Et pendant que j'y suis, il ne faut surtout pas faire WHERE b.id_budget = ".$_GET['id_budget']. C'est une faille qui permet de réaliser des injection SQL. Il faut que tu vérifies que ce que tu reçois est bien ce que tu attend (une valeur numérique), ou au moins que tu échappes les caractères spéciaux avec mysql_real_escape_strings.

Discussions similaires

  1. Réponses: 2
    Dernier message: 14/12/2011, 13h12
  2. Réponses: 5
    Dernier message: 13/02/2008, 17h52
  3. Réponses: 5
    Dernier message: 04/10/2006, 18h49
  4. [Tableaux] Tableau multi dimensionnel
    Par gids01 dans le forum Langage
    Réponses: 7
    Dernier message: 02/10/2006, 16h18
  5. [Tableaux] tri sur un tableau multi-dimensionnel
    Par nicoaix dans le forum Langage
    Réponses: 1
    Dernier message: 12/04/2006, 21h23

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