Optimisation de requête

GrandMa
Invité n'ayant pas de compte PHPfrance

04 avr. 2005, 19:44

Bonjour à tous,
Lorsqu'on a un champs numérique et que l'on veuille faire des requêtes sur des catégories de réponse, comment optimiser son code pour ne pas faire autant de requêtes?
Exemple: la variable vote est numérique et prend les valeurs de 0 à 100, en plus de NULL.
Je voudrais connaître le nombre de réponses par catégorie...Y a-t-il moyen de faire une seule requête au lieu de ces 5? Merci à l'avance.
$sql1 = "SELECT id FROM data WHERE vote < 25 ";
$res1 = mysql_query($sql1) or die('erreur : '.mysql_error());
if($res1 = mysql_query($sql1))
{	$nb0024 = mysql_num_rows($res1);}

$sql2 = "SELECT id FROM data WHERE vote BETWEEN 25 AND 49 ";
$res2 = mysql_query($sql2) or die('erreur : '.mysql_error());
if($res2 = mysql_query($sql2))
{	$nb2549 = mysql_num_rows($res2);}

$sql3 = "SELECT id FROM data WHERE vote BETWEEN 50 AND 74 ";
$res3 = mysql_query($sql3) or die('erreur : '.mysql_error());
if($res3 = mysql_query($sql3))
{	$nb5074 = mysql_num_rows($res3);}

$sql4 = "SELECT id FROM data WHERE First_Year >=75 ";
$res4 = mysql_query($sql4) or die('erreur : '.mysql_error());
if($res4 = mysql_query($sql4))
{	$nb7500 = mysql_num_rows($res4);}

$sql5 = "SELECT id FROM data WHERE vote IS Null ";
$res5 = mysql_query($sql5) or die('erreur : '.mysql_error());
if($res5 = mysql_query($sql5))
{	$nbNull = mysql_num_rows($res5);}

GrandMa
Invité n'ayant pas de compte PHPfrance

05 avr. 2005, 00:59

Est-ce ambigu comme question? Quelqu'un svp?

Administrateur PHPfrance
Administrateur PHPfrance | 11457 Messages

05 avr. 2005, 02:02

Sachant que tu veux tester tes données selon 5 intervalles de valeurs,
je ne vois pas comment se passer de faire 5 requêtes.

Pour soulager tes doigts et tes yeux, tu peux essayer de factoriser ta requête,
mais cela ne changera en rien l'utilisation de ton serveur de BD.

Lance tout de même ta requête sur un count(*),
c'est plus rapide qu'un SELECT sur une donnée que tu recense ensuite.
for (i=0 ; i<4 ; i++)
    { $sql = "SELECT count(id) FROM data WHERE First_Year BETWEEN ".(25*i)." AND ".(25*(i+1)-1);
      // ...
    }

Administrateur PHPfrance
Administrateur PHPfrance | 11457 Messages

05 avr. 2005, 02:07

Tiens, je viens d'avoir une idée, mais je ne l'ai pas testée.
Je te laisse vérifier.

Si ça marche, cela permet de ne faire qu'une lecture de la table au lieu de 5.
Ça peut être intéressant en terme de performances...
SELECT count(t1.id), count(t2.id), count(t3.id), count(t4.id), count(t5.id)
FROM data t1, data t2, data t3, data t4, data t5
WHERE t1.vote < 25
AND t2.vote BETWEEN 25 AND 49
AND t3.vote BETWEEN 50 AND 74
AND t4.vote >= 75
AND t5.vote IS NULL
Si ça ne marche pas, ne m'en veux pas. Je suis crevé, j'vais m'coucher... :sleeping:

Administrateur PHPfrance
Administrateur PHPfrance | 11457 Messages

05 avr. 2005, 02:09

Non, en le relisant, ça me paraît bizarre... ça doit pas marcher.
En fait, je ne crois pas que tu puisses te passer de 5 requêtes.

Enfin... j'sais plus.

(Wouaaaah, j'suis cre-vé !)

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

05 avr. 2005, 02:09

Il doit être possible d'exécuter ça, je doute que cela soit beaucoup plus rapide que la solution d'albat:

Code : Tout sélectionner

SELECT FLOOR(vote / 25) AS tranche, COUNT(*) AS total FROM data GROUP BY tranche
La tranche 0 va de 0 à 24, tranche 1 de 25 à 49, tranche n de (n * 25) à (n * 25 + 24).

PS: je présume que le "First_Year" de la requêtes 4 était en fait "vote"

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

05 avr. 2005, 02:10

PPS: mon post faisait référence au premier post d'albat.

Administrateur PHPfrance
Administrateur PHPfrance | 11457 Messages

05 avr. 2005, 02:13

Hubert, ta méthode me plaît beaucoup.
Il faudrait que je la teste mais je pense que c'est bon.
Et c'est très élégant ! =D>

De manière générale, il vaut mieux effectuer les traitements (calculs) en SQL qu'en PHP.

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

05 avr. 2005, 02:20

Merci ;)

Au fait, j'ai oublié de préciser que la requête retournerait 4 tranches (de 0 à 3) plus une cinquième tranche NULL. Sauf évidemment si tu as des valeurs supérieures à 99... Ah, d'ailleurs je viens de voir que ton compteur allait de 0 à 100 inclus :\

À toi GrandMa d'ajouter le résultat de la tranche 4 (si elle existe) à la tranche 3 ou de prévoir ce cas dans la requête elle-même:

Code : Tout sélectionner

SELECT FLOOR(LEAST(99, vote) / 25) AS tranche, COUNT(*) AS total FROM data GROUP BY tranche

GrandMa
Invité n'ayant pas de compte PHPfrance

05 avr. 2005, 02:47

Merci à vous deux les Boyz...

@Hubert: ta dernière solution me met l'ensemble des résultats dans une seule tranche (la 3ème), ce qui est non conforme à la nature de mes données. Une autre piste? Merci à l'avance.

PS: "First_Year" de la requête 4 était effectivement "vote", typo lors de l'écriture sur le forum.

Invité
Invité n'ayant pas de compte PHPfrance

05 avr. 2005, 03:00

Désolée je vous ai induite en erreur...Ça marche mais ça ne fonctionne que pour les 4 premières catégories (0 à 3), cependant la dernière catégorie (3, qui est supposé être 75% ou plus) comprend également les NULL...