Trie par ordre alpha à double entrée ?

Eléphanteau du PHP | 38 Messages

04 juil. 2012, 12:39

Bonjour,

J'ai une problématique en terme de performance au niveau de l'utilisation de mémoire (memory_get_peak_usage beaucoup trop élevé) car je passe par une variable temporaire pour trier une liste par ordre alpha sur deux champs, je sais pas si je peux faire autrement.

J'ai une table contenant des milliers de livres.
Un livre a un nom et un nom_secondaire , dans mon listing (choix lettre T = je liste les livres dont le nom OU le nom_secondaire commence par T).

Je fais donc :
$query = mysql_query("SELECT nom, nom_secondaire FROM livres WHERE nom LIKE 't%'");
$query1 = mysql_query("SELECT nom, nom_secondaire FROM livres WHERE nom_secondaire LIKE 't%'");
$tmp = array();
while(list($nom,$nom_secondaire) = mysql_fetch_row($query)) {
  $tmp[strtolower($nom)] = array('nom'=>$nom,'nom_secondaire'=>$nom_secondaire);
}
while(list($nom,$nom_secondaire) = mysql_fetch_row($query1)) {
  $tmp[strtolower($nom_secondaire)] = array('nom'=>$nom_secondaire,'nom_secondaire'=>$nom);
}
ksort($tmp); //Je tri le tableau pour ranger par ordre alpha par nom et nom secondaire
//(un livre peut pas avoir un nom secondaire qu'un autre livre aurait en titre principal)

echo '<ul>';
foreach($tmp as $k => $v) {
  echo '<li><a href="/livres/'.urlencode($v['nom']).'.html">'.$v['nom'].' ('.$v['nom_secondaire'].')</a></li>';
}
echo '</ul>';
Et mon soucis c'est que $tmp est énorme mais je vois pas comment faire sans lui pour trier par ordre alpha mes livres sur 2 champs (titre et titre secondaire).

Quelqu'un aurait une meilleure idée ?

Merci.

ViPHP
xTG
ViPHP | 7331 Messages

04 juil. 2012, 13:26

Je vois pas pour l'utilisation autrement que par deux arrays.
Par contre voilà déjà quelques amélioration de performances mémoire :
$query = mysql_query("SELECT nom, nom_secondaire FROM livres WHERE nom LIKE 't%'");
$tmp = array();
while(list($nom,$nom_secondaire) = mysql_fetch_row($query)) {
  $tmp[strtolower($nom)] = array('nom'=>$nom,'nom_secondaire'=>$nom_secondaire);
}
mysql_free_result($query);
$query1 = mysql_query("SELECT nom, nom_secondaire FROM livres WHERE nom_secondaire LIKE 't%'");
while(list($nom,$nom_secondaire) = mysql_fetch_row($query1)) {
  $tmp[strtolower($nom_secondaire)] = array('nom'=>$nom_secondaire,'nom_secondaire'=>$nom);
}
mysql_free_result($query1);
ksort($tmp); //Je tri le tableau pour ranger par ordre alpha par nom et nom secondaire
//(un livre peut pas avoir un nom secondaire qu'un autre livre aurait en titre principal)

echo '<ul>';
foreach($tmp as $k => $v) {
  echo '<li><a href="/livres/'.urlencode($v['nom']).'.html">'.$v['nom'].' ('.$v['nom_secondaire'].')</a></li>';
}
echo '</ul>';
Tu n'as pas des doublons aussi à cause de tes requêtes ? Faudrait voir ce que cela peut donner en ne prenant dans la seconde que les livres non sélectionnés par la première.

Eléphanteau du PHP | 38 Messages

04 juil. 2012, 13:34

Ca me rassure un peu alors

Merci pour le free results même si ça libère quasi rien par rapport a la taille de $tmp lol

Alors si j'ai des doublons mais c'est voulu, car quand tu cherches dans la liste, si tu connais que le nom secondaire, faut qu'un même livre soit listé 2 fois une fois pour chaque nom qu'il a :)

ViPHP
xTG
ViPHP | 7331 Messages

04 juil. 2012, 13:42

Éventuellement voir si le tri ne peut pas être fait via SQL ? Tu y gagnerais en nombre de lecture/copie et un algo de tri déporté.
J'entends par là un truc du genre :
SELECT nom, nom_secondaire FROM livres WHERE nom LIKE 't%' ORDER BY LOWER(nom) ASC
SELECT nom_secondaire AS nom, nom AS nom_secondaire FROM livres WHERE nom_secondaire LIKE 't%' ORDER BY LOWER(nom_secondaire) ASC
Pas sûr de mon coup par contre pour les alias de la seconde requête. :mrgreen:

Eléphanteau du PHP | 38 Messages

04 juil. 2012, 13:46

Le soucis c'est qu'il faudra encore passer par une variable temporaire car il faut au finale une liste triée de ces deux requêtes :)

La si je parcours la première et affiche les résultats puis la seconde, ce sera pas dans l'ordre.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

04 juil. 2012, 14:18

Et un truc de ce genre :
SELECT
	nom, nom_secondaire
FROM
	livres
WHERE
	nom LIKE 't%' OR nom_secondaire LIKE 't%'
ORDER BY
	nom, nom_secondaire
Devrait retourner les livres dont le nom ou le nom secondaire commence par "t", et les tris par le nom, et en cas de nom identiques, tri par le nom secondaire.
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer