par
Hubert Roksor » 06 févr. 2006, 08:35
Désolé de ne pas rentrer dans les détails (mes corn-flakes sont en train de ramollir) mais voici quelques infos/commentaires qui devraient intéresser charabia. Si tu as besoin de précisions n'hésite pas.
[Comment faire pour] afficher en face de chaque sous catégorie le nombre d'enregistrements [...]
Tu pourrais le faire en une seule requête, mais elle serait assez moche et pas forcément plus rapide (voire carrément plus lente). Le mieux est d'en faire deux: la première récupère les noms et les IDs des catégories à afficher (dans l'ordre) et la seconde les sous-catégories qui leur sont affiliées. J'imagine que tu utilises deux tables étant donné que tu n'as pas posté la structure de tes données:
Code : Tout sélectionner
SELECT c.cat_id, c.cat_name, COUNT(sc.ss_cat_id) AS ss_cat_cnt
FROM categories c
LEFT JOIN ss_categories sc ON sc.cat_id = c.cat_id
ORDER BY cat_order
Code : Tout sélectionner
SELECT ss_cat_id, ss_cat_name
FROM ss_categories
WHERE cat_id IN (...)
ORDER BY ss_cat_order
Pourquoi utiliser deux requêtes au lieu d'une ? Je n'ai pas d'explication unique, je tire cet enseignement d'observations. Une des explications est la réduction de la quantité de données qui est envoyé par le serveur. En effet, dans 99,99% des cas on se retrouve obligé de récupérer le nom de la catégorie en même temps que le nom de la sous-catégorie. Du coup, le nom de la catégorie ainsi que toute autre champs requêté se retrouve dans le résultat => plus de traffic, plus de champs à mettre dans la variable PHP qui sert de container aux données, etc...
Comme autres explications on pourrait aussi imaginer la réduction de données, mais cette fois-ci au niveau du tri des enregistrements => tuple plus gros == tri plus lent, même si ce n'est plus vraiment vrai depuis MySQL 4.1. On pourrait ajouter l'overhead dû à la jointure ou une autre demi-douzaine de facteurs...
Je n'ai pas testé cette requête mais si tu tiens absolument à le faire en une seule requête, elle ressemblera probablement à cela: (ne satisfait pas ONLY_FULL_GROUP_BY)
Code : Tout sélectionner
SELECT c.cat_id, c.cat_name, COUNT(sc2.sub_cat_id) AS sub_cat_cnt, sc.sub_cat_id, sc.sub_cat_name
FROM categories c, sub_categories sc, sub_categories sc2
WHERE sc.cat_id = c.cat_id
AND sc2.cat_id = c.cat_id
GROUP BY c.cat_id, sc.cat_id
ou cela (devrait être ANSI, TRADITIONAL)
Code : Tout sélectionner
SELECT tmp.cat_id, tmp.cat_name, tmp.sub_cat_cnt, sc.sub_cat_id, sc.sub_cat_name
FROM (
SELECT c.cat_id, c.cat_name, COUNT(sc2.sub_cat_name) AS sub_cat_cnt
FROM categories c, sub_categories sc2
WHERE c2.cat_id = c.cat_id
GROUP BY c.cat_id
) AS tmp, sub_categories sc
WHERE sc.cat_id = c.cat_id
ORDER BY c.cat_order, sc.sub_cat_order
Désolé de ne pas rentrer dans les détails (mes corn-flakes sont en train de ramollir) mais voici quelques infos/commentaires qui devraient intéresser charabia. Si tu as besoin de précisions n'hésite pas.
[quote="charabia"][Comment faire pour] afficher en face de chaque sous catégorie le nombre d'enregistrements [...][/quote]
Tu pourrais le faire en une seule requête, mais elle serait assez moche et pas forcément plus rapide (voire carrément plus lente). Le mieux est d'en faire deux: la première récupère les noms et les IDs des catégories à afficher (dans l'ordre) et la seconde les sous-catégories qui leur sont affiliées. J'imagine que tu utilises deux tables étant donné que tu n'as pas posté la structure de tes données:
[code]SELECT c.cat_id, c.cat_name, COUNT(sc.ss_cat_id) AS ss_cat_cnt
FROM categories c
LEFT JOIN ss_categories sc ON sc.cat_id = c.cat_id
ORDER BY cat_order[/code]
[code]SELECT ss_cat_id, ss_cat_name
FROM ss_categories
WHERE cat_id IN (...)
ORDER BY ss_cat_order[/code]
Pourquoi utiliser deux requêtes au lieu d'une ? Je n'ai pas d'explication unique, je tire cet enseignement d'observations. Une des explications est la réduction de la quantité de données qui est envoyé par le serveur. En effet, dans 99,99% des cas on se retrouve obligé de récupérer le nom de la catégorie en même temps que le nom de la sous-catégorie. Du coup, le nom de la catégorie ainsi que toute autre champs requêté se retrouve dans le résultat => plus de traffic, plus de champs à mettre dans la variable PHP qui sert de container aux données, etc...
Comme autres explications on pourrait aussi imaginer la réduction de données, mais cette fois-ci au niveau du tri des enregistrements => tuple plus gros == tri plus lent, même si ce n'est plus vraiment vrai depuis MySQL 4.1. On pourrait ajouter l'overhead dû à la jointure ou une autre demi-douzaine de facteurs...
Je n'ai pas testé cette requête mais si tu tiens absolument à le faire en une seule requête, elle ressemblera probablement à cela: (ne satisfait pas ONLY_FULL_GROUP_BY)
[code]SELECT c.cat_id, c.cat_name, COUNT(sc2.sub_cat_id) AS sub_cat_cnt, sc.sub_cat_id, sc.sub_cat_name
FROM categories c, sub_categories sc, sub_categories sc2
WHERE sc.cat_id = c.cat_id
AND sc2.cat_id = c.cat_id
GROUP BY c.cat_id, sc.cat_id[/code]
ou cela (devrait être ANSI, TRADITIONAL)
[code]SELECT tmp.cat_id, tmp.cat_name, tmp.sub_cat_cnt, sc.sub_cat_id, sc.sub_cat_name
FROM (
SELECT c.cat_id, c.cat_name, COUNT(sc2.sub_cat_name) AS sub_cat_cnt
FROM categories c, sub_categories sc2
WHERE c2.cat_id = c.cat_id
GROUP BY c.cat_id
) AS tmp, sub_categories sc
WHERE sc.cat_id = c.cat_id
ORDER BY c.cat_order, sc.sub_cat_order[/code]