Administrateur PHPfrance |
13231 Messages
19 déc. 2010, 15:59
La solution "pour chaque ligne de la requête 1, je fait une requête" est très très très très (très, ...) mauvaise.
Pourquoi ? Le nombre de requêtes !!
Si tu as 10 billets, tu auras 11 requêtes (la 1ere requête pour les billets, et une requête par billetst), pour 100 billets : 101 requêtes, ...
Quand on sais que ce qui prend le plus de temps dans un programme, ce sont les accès aux fichiers sur le disque et les requêtes en bases de données, on vois que la solution de multiplier les requêtes est très très (bref, vous m'avez compris) mauvaise.
La bonne solution est de faire une jointure, mais de tenir compte de ça quand tu parcours la liste de tes résultats.
Voici un petit exemple pour éviter les soucis, tout en optimisant le nombre de requêtes :
<?php
// Utilisation d'un LEFT JOIN pour remonter les billets sans commentaire
// NB : utiliser JOIN, LEFT JOIN, OUTER JOIN est plus optimisé qu'une jointure par le WHERE
$requete = <<<EOF
SELECT
billets.id, billets.titre, billets.contenu, DATE_FORMAT(billets.date_creation, \'%d/%m/%Y à %Hh%imin%ss\') AS date_creation_fr,
commentaires.id, commentaires.auteur, commentaires.com, commentaires.id_billet
FROM billets LEFT JOIN commentaires ON billets.id = commentaires.id_billet
ORDER BY date_creation_fr DESC
LIMIT 0, 5
EOF;
// Cette requête va retourner plusieurs fois les mêmes billets, s'ils ont plus de 1 commentaire.
// Il est donc nécessaire de retravailler le résultat pour avoir la liste des billets, et les commentaires qui leurs sont associés
$reponse = $bdd->exec($requete)
OR die(print_r($bdd->errorInfo()));
// Initialisation du tableau qui contiendra le résultat de la requête
$a_billet = array();
foreach( $reponse->fetch() as $ligne )
{
$id_billet = $ligne[1];
$id_commentaire = $ligne [5];
// Si le billet n'a pas déjà été parcouru, on le créé dans le tableau.
// Ici, il est important de noter que je créé un tableau destiné à contenir les commentaires de ce billet
if( array_key_exist($id_billet, $a_billet) )
{
$a_billet[$id_billet] = array(
'id' => $ligne[1],
'titre' => $ligne[2],
'contenu' => $ligne[3],
'date_creation_fr' => $ligne[4],
'commentaires' => array(), // Création du tableau destiné à contenir les commentaires
);
}
// Ajout du commentaire dans le billet
$a_billet[$id_billet]['commentaires'] = array(
'id' => $ligne['5'],
'auteur' => $ligne['6'],
'com' => $ligne['7'],
);
}
// Affichage du tableau chargé
echo '<pre>';
print_r($a_billet);
echo '</pre>';