Annonce

#1 2006-03-27 12:00:10

rub
Former Piwigo Team
Lille
2005-08-26
5239

Utilisation de $user['forbidden_categories']?

Dans la version [Subversion] r1105 de la BSF, au niveau de la notification par mail, pour récupérer le nombre de nouveautés des utilisateurs, j'exécute pour CHAQUE USER la fonction news de l'unité functions_notification.inc.php, qui elle-même éxecute de NOMBREUSES REQUêTES.

Donc, plus il y a de users, plus il y a de requêtes à faire.

Je suis entrain d'optimiser le traitement pour que quelque soit le nombre de users, le temps d'execution soit à peu près le même et pour ca, je voudrais executer les requêtes de la functions en 1 SEULE FOIS pour l'ensemble des UTILISATEURS. Le petit hic, c'est l'utilisation de $user['forbidden_categories'] qui ne me permet pas de faire les requêtes sur plusieurs utlisateus en même temps.

Pour ne plus utiliser $user['forbidden_categories'], plusieurs possibilités me viennet à l'esprit:
  o (Solution 1) tout d'abord, transposer $user['forbidden_categories'] dans une nouvelle table (user_id, cat_id) et faire les jointure left + conditions pour faire pareil que $user['forbidden_categories']
    > Cette transposition peut être faire dans un table temporaire
    > ou dans une table fixe qui sera alimenté en même temps que le champs forbidden_categories de la tabcle cache
    Si on adopte cette table, faut-il ou non modifier toutes les requêtes et supprimer $user['forbidden_categories']
  o (Solution 2) Mais après reflexion, je me suis dit qu'il fallait mieux ne pas utliser de nouvelles tables mais faire les jointures directement avec les tables #phpwebgallery_group_access, #phpwebgallery_user_access, #phpwebgallery_categories (status = public) (Utiliser les 3 tables avec un UNION). (Par contre, contrairement à la génération de $user['forbidden_categories'], je ne gérerais pas les catégories verrouillées car ca complique encore la requête et c'est par necessaire pour compter les nouveaux éléments)


Je vais partir sur la solution de reprendre les tables existantes (Solution 2).
J'evoquais plusieurs possibilités car j'ai lu que certains voulaientt des changements concernant la gestion du cache, donc si la solution 1 était une de celles prévus, c'est peut-être le moment pour commencer.

Hors ligne

#2 2006-03-28 00:15:53

rub
Former Piwigo Team
Lille
2005-08-26
5239

Re: Utilisation de $user['forbidden_categories']?

En fait, pour résumer, je voudrais remplacer :

les requêtes, executés pour CHAQUE utlisateur, du type suivant

Code:

SELECT DISTINCT c.id AS comment_id
  FROM phpwebgallery_comments AS c
     , phpwebgallery_image_category AS ic
  WHERE c.image_id = ic.image_id
    AND c.validation_date > ''
    AND c.validation_date <= '2006-03-27 23:31:33'
    AND category_id NOT IN (
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,28,29,
30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,
56,57,58,59,60,61,62,63,65,67,69,71,72,74,76,78,80,82,84,87,89,91,92,95,96,97,
98,101,102,104,106,107,109,110,112,114,116,118,119,121,123,125,126,128,130,131,
133,139,141,142,145,147,148,149,153,155,156,158,162,163,165,167,169,171,172,
173,174,177,178,181,182,185,186,187,188,189,190,191,192,193,199,218,219,220,
221,222,223,224,225,226,228,229,230,231,232,233,276,277,278,279,280,281,282,
283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,
302,303,304,305,306,307,308,309,310,311,312,313,314,325,327,334,344,349,359,
360,361,362,366,367,370,371,372,373,374,378,379,380,381,382,383,384,385,386,
387,388,389,390,391,392,393,398,401,402,406,409,411,413,416,418,419,420,423,
424,427,428,429,433,434,-1
);

par cette requête executée UNE seule fois pour l'ensemble des utilisateurs

Code:

SELECT user_id, count(DISTINCT c.id)
  FROM phpwebgallery_comments AS c
     , phpwebgallery_image_category AS ic
     ,
        (
        select user_id, cat_id
          from phpwebgallery_group_access ga, phpwebgallery_user_group ug
          where ga.group_id = ug.group_id
            and ug.user_id in (1,3,5,6,7)

        union

        select user_id, cat_id
          from phpwebgallery_user_access
          where user_id in (1,3,5,6,7,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45)

        union

        select u.id user_id, c.id cat_id
          from phpwebgallery_categories c, phpwebgallery_users u
          where c.status = 'public'
            and u.id in (1,3,5,6,7,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45)
        ) authorized_cat

  WHERE c.image_id = ic.image_id
    AND c.validation_date > ''
    AND c.validation_date <= '2006-03-27 23:31:33'
    AND authorized_cat.cat_id = category_id
  GROUP BY user_id
;

Par contre, pour que cette requete fonctionne bien, il faut que les tables soit optimisée. J'ajouterais une optimisation des tables à chaque notification. Qu'en pensez-vous?

Par contre, je ne sais pas si cette requête est compatible avec la version minimal de myql supportée par pwg. Pierrick ou quelqu'un d'autre pourrait me confirmer assez vite, si c'est OK avec la version miminal de mysql?

Hors ligne

#3 2006-03-28 05:13:31

rvelices
Équipe Piwigo
2005-12-29
1417

Re: Utilisation de $user['forbidden_categories']?

Malheureusement je n'ai pas MySql 3 pour confirmer si ca marche ...
Mais je pense que les perfs ne seront pas si mauvaises que ca meme si tu fais plusieurs requetes par utilisateur... (et puis meme si ca prend 5 secondes, on ne va pas faire ca tous les jours)

Hors ligne

#4 2006-03-28 06:51:36

rub
Former Piwigo Team
Lille
2005-08-26
5239

Re: Utilisation de $user['forbidden_categories']?

rvelices a écrit:

Malheureusement je n'ai pas MySql 3 pour confirmer si ca marche ...

Dommage...

rvelices a écrit:

Mais je pense que les perfs ne seront pas si mauvaises que ca meme si tu fais plusieurs requetes par utilisateur... (et puis meme si ca prend 5 secondes, on ne va pas faire ca tous les jours)

Bha, en fait, je teste avec 60 utilisateurs et ca fait à peu près 700 requêtes et on arrive facile à 24 secondes... J'ai modifié les requêtes de la fonction news pour mettre le count dans le sql et on est passé à 18 s... Avec les tables optimisées, la nouvelle requête est executée en moins d'une seconde, ce qui ferait au total un temps < à 5 secondes, je pense... sans compter l'envoi des mail par le smtp qui être long aussi...
Bref, le but est d'éviter d'arriver au time-out de la page php.. je vais aussi limiter l'envoi à un nombre fini d'utilisateur à chaque passe (comme pour les miniatures par exemple...)


Sinon pour l'optimisation des tables, elle n'est pas à faire à chaque fois mais il faudrait plus créer un lien dans maintenance et le faire aussi à chaque upgrade de pwg...

Hors ligne

#5 2006-03-28 10:16:19

plg
Équipe Piwigo
Nantes, France, Europe
2002-04-05
12644

Re: Utilisation de $user['forbidden_categories']?

(désolé rub, ce post risque de briser quelques espoirs)

Les requêtes imbriquées, c'est du MySQL 4.1, donc c'est non. Que MySQL 4.0 devienne éventuellement le prérequis à partir de la branche 1.6 de PhpWebGallery, pourquoi pas (le code actuel ne l'impose pas il me semble, mais je ne peut plus vérifier étant moi-même passé en 4.0 depuis plus de 6 mois).

Remplacer la concaténation des identifiants de catégories inaccessibles stockée en cache utilisateur par une table associant {user_id,category_id}, c'est non. Car un NOT IN (...) est bien plus rapide qu'une jointure. Pour information, cette table que tu proposes existait en des temps immémoriaux (en branche 1.3) et elle a été très avantageusement remplacé par user_cache.forbidden_categories, sans conteste. Je rappelle que nous devons concentrer nos efforts d'amélioration des performances sur category.php/index.php et picture.php, les autres pages ne doivent pas être trop lentes, mais ce n'est pas la priorité.

Ne pas prendre en compte les catégories verrouillées ??? Bien sûr que si, ce serait une erreur fonctionnelle que de ne pas le faire et un bug à corriger en branche 1.6.

Les requêtes que tu montres supposent que tous les utilisateurs ont été notifiés précédemment à la même date. C'est un raccourci bien trop facile à mon avis. Tu peux très bien vouloir à un moment donné notifié 35 utilisateurs dont la date de dernière notification par mail est différente pour chacun. Dans ce cas là, t'es bon pour pour faire 35 requêtes...

Tu remarques évidemment que ces problèmes ne se posent pas avec la notification tirée (flux RSS) par rapport à la notification poussée (mail) car on peut espèrer que chaque utilisateur interroge son flux en décalé.

Mon avis est que la seule solution raisonnable est de limiter le nombre d'utilisateurs notifié à la fois.


Les historiens ont établi que Pierrick était le premier utilisateur connu de Piwigo.

Hors ligne

#6 2006-03-28 10:32:46

VDigital
Former Piwigo Team
Montpellier (FR)
2005-05-04
15127

Re: Utilisation de $user['forbidden_categories']?

z0rglub a écrit:

Les requêtes que tu montres supposent que tous les utilisateurs ont été notifiés précédemment à la même date. C'est un raccourci bien trop facile à mon avis. Tu peux très bien vouloir à un moment donné notifié 35 utilisateurs dont la date de dernière notification par mail est différente pour chacun. Dans ce cas là, t'es bon pour pour faire 35 requêtes...

Je suis d'accord avec toi sur tous les points.

:idea:
J'ai peut être une autre solution à vous proposer, dès que j'ai un peu de temps pour y réfléchir, je vous ferai une proposition d'une logique différente.

8-)


Vincent -« Plus vidéaste averti que photographe amateur... »
La galerie - Le blog   

Piwigo est une application libre de gestion de photos en ligne.

Hors ligne

#7 2006-03-28 11:50:50

rub
Former Piwigo Team
Lille
2005-08-26
5239

Re: Utilisation de $user['forbidden_categories']?

z0rglub a écrit:

(désolé rub, ce post risque de briser quelques espoirs)

Non, non, je me doutais un peu des réponses mais j'avais envie d'en discuter...

z0rglub a écrit:

Les requêtes imbriquées, c'est du MySQL 4.1, donc c'est non. Que MySQL 4.0 devienne éventuellement le prérequis à partir de la branche 1.6 de PhpWebGallery, pourquoi pas (le code actuel ne l'impose pas il me semble, mais je ne peut plus vérifier étant moi-même passé en 4.0 depuis plus de 6 mois).

Je m'en doutais un peu... déjà que mes requêtes imbriqués dans le where ne passaient pas, je me doutais que celles imbriquées dans le from, ne le serais pas aussi...

Oui pourquoi MySQL 4.0 comme pré-requis, mais si c'est pas nécessaire, on reste bien sur à la version 3.0...

Par contre, je suis triste de ne pas pourvoir faire de réquêtes imbriquées, je trouve ca tres pratique...


z0rglub a écrit:

Remplacer la concaténation des identifiants de catégories inaccessibles stockée en cache utilisateur par une table associant {user_id,category_id}, c'est non. Car un NOT IN (...) est bien plus rapide qu'une jointure. Pour information, cette table que tu proposes existait en des temps immémoriaux (en branche 1.3) et elle a été très avantageusement remplacé par user_cache.forbidden_categories, sans conteste.

Ce qui est vrai si on fait l'interrogation pour un seul user (c'est peut-être plus rapide mais c'est plus qussi simple à écrire aussi)...
Pour n utilisateurs d'un coup, ce n'est pas le cas (mais sauf NBM, nous n'avons pas le cas)...
Par contre, je suis étonné que la jointure soit plus longue que le not in... (ca doit dépendre du nombre de forbidden, ect...)...

z0rglub a écrit:

Je rappelle que nous devons concentrer nos efforts d'amélioration des performances sur category.php/index.php et picture.php, les autres pages ne doivent pas être trop lentes, mais ce n'est pas la priorité.

Discuter sur l'optimisation d'autres pages peut aussi aider à optimiser les 2 pages principales ;-)

z0rglub a écrit:

Ne pas prendre en compte les catégories verrouillées ??? Bien sûr que si, ce serait une erreur fonctionnelle que de ne pas le faire et un bug à corriger en branche 1.6.

Ca serait une erreur fonctionnelle dans les fonctionnalités classiques mais pas pour la notification (RSS ou mail).
Par exemple, si on a:
  o création d'une nouvelle catégorie C
  o cette catégorie C est verrouillée
  o demande de notification RSS ou mail
  o la nouvelle catégorie C ne sera pas comptée dans la notification car elle est verrouillée
  o dévérrouillage de la catégorie C
  o demande de notification RSS ou mail
  o la nouvelle catégorie C ne sera pas comptée dans la notification car la date de demande sera trop récente par rapport à la date de la catégorie

C'est pour ca que la notion de verrouillage ne devrait pas être faite pour la notification.
Pour moi, le verrouillage, c'est empêcher temporaire l'utilisateur de voir une catégorie car elle est en cours de mise à jour. Mais, on peut quand même notifier qu'elle est présente.

Pour me contredire, si la catégorie est verrouillée, c'est que les images contenues se sont pas figés (pas assez ou trop d'images) et par conséquent, il ne faut pas les notifier...

Bref, tout ca pour dire, pour la notification (rss/mail) ce n'est peut-être pas une erreur fonctionnelle ni un bug, tout dépend par ce qu'on entend par verrouillage.


z0rglub a écrit:

Les requêtes que tu montres supposent que tous les utilisateurs ont été notifiés précédemment à la même date. C'est un raccourci bien trop facile à mon avis. Tu peux très bien vouloir à un moment donné notifié 35 utilisateurs dont la date de dernière notification par mail est différente pour chacun. Dans ce cas là, t'es bon pour pour faire 35 requêtes...

Oui, oui, je savais... Les notifications par mails étant faire par paquets, les querys auraient été faites par paquets suivant les dates... Donc pour 35 utilisateurs entr 1 et 35 requêtes suivant les dates.


z0rglub a écrit:

Tu remarques évidemment que ces problèmes ne se posent pas avec la notification tirée (flux RSS) par rapport à la notification poussée (mail) car on peut espèrer que chaque utilisateur interroge son flux en décalé.

Bien sur... NBM est la 1er (?) partie qui utilise les propriétés de chaque user pour construire quelque chose... D'habitude, c'est soit de la gestion de users, soit la "construction" de quelque chose pour un seul user...

z0rglub a écrit:

Mon avis est que la seule solution raisonnable est de limiter le nombre d'utilisateurs notifié à la fois.

Ok, c'est vendu... ca sera limité par un paramètre.
(De touté façon, mais si j'avais utilisé les requêtes imbriquées, j'aurais mis un paramètre car le sendmail peut aussi avoir des temps de réponses non correctes.)
J'ai aussi modifié un peu les requêtes pour faire le count dans la query et c'est un peu plus rapide aussi

Code:

function new_comments($start, $end)
{
  global $user;
  
  $query = '
SELECT DISTINCT c.id AS comment_id
  FROM '.COMMENTS_TABLE.' AS c
     , '.IMAGE_CATEGORY_TABLE.' AS ic
  WHERE c.image_id = ic.image_id
    AND c.validation_date > \''.$start.'\'
    AND c.validation_date <= \''.$end.'\'
    AND category_id NOT IN ('.$user['forbidden_categories'].')
;';
  return array_from_query($query, 'comment_id');
}

$res := count(new_comments(...,...));

est remplacé par

Code:

function new_comments($start, $end)
{
  global $user;
  
  $query = '
SELECT count(DISTINCT c.id)
  FROM '.COMMENTS_TABLE.' AS c
     , '.IMAGE_CATEGORY_TABLE.' AS ic
  WHERE c.image_id = ic.image_id
    AND c.validation_date > \''.$start.'\'
    AND c.validation_date <= \''.$end.'\'
    AND category_id NOT IN ('.$user['forbidden_categories'].')
;';

  list($count) = mysql_fetch_array(pwg_query($query));
  return $count;
}

$res := new_comments(...,...);

Je verrais aussi s'il n'y a pas encore de petites modifications à faire pour optimiser le tout...

VDigital a écrit:

:idea:
J'ai peut être une autre solution à vous proposer, dès que j'ai un peu de temps pour y réfléchir, je vous ferai une proposition d'une logique différente.

On est impatient ;-)

Hors ligne

#8 2006-03-28 12:07:51

plg
Équipe Piwigo
Nantes, France, Europe
2002-04-05
12644

Re: Utilisation de $user['forbidden_categories']?

rub, si tu modifies les fonctions ainsi, on ne pourra plus avoir les détails qui sont au programmes de futures améliorations de la notification, comme la liste des noms des catégories mises à jour. En tout cas si tu veux modifier en ce sens, il faut renommer la fonction... en nb_new_comments.


Les historiens ont établi que Pierrick était le premier utilisateur connu de Piwigo.

Hors ligne

#9 2006-03-28 12:21:01

rub
Former Piwigo Team
Lille
2005-08-26
5239

Re: Utilisation de $user['forbidden_categories']?

Effectivement, je vais en tenir compte...

Hors ligne

#10 2006-03-29 11:41:18

VDigital
Former Piwigo Team
Montpellier (FR)
2005-05-04
15127

Re: Utilisation de $user['forbidden_categories']?

rub a écrit:

VDigital a écrit:

:idea:
J'ai peut être une autre solution à vous proposer, dès que j'ai un peu de temps pour y réfléchir, je vous ferai une proposition d'une logique différente.

On est impatient ;-)

L'idée ne murit pas assez vite, mais je n'oublie pas, tu ne l'auras pas pour la 1.6, j'ai même peur de mettre avancé et d'être dans une impasse.


Vincent -« Plus vidéaste averti que photographe amateur... »
La galerie - Le blog   

Piwigo est une application libre de gestion de photos en ligne.

Hors ligne

#11 2006-04-10 16:19:31

mathiasm
Former Piwigo Team
2006-02-06
2692

Re: Utilisation de $user['forbidden_categories']?

rub a écrit:

Code:

'[...]AND c.validation_date > \''.$start.'\'[...]'

Pourquoi ne pas remplacer les ' externes par des " pour éviter d'avoir à échapper les simples quotes de la requete?

Question subsidiaire:
est-il mieux (?) de faire 'xx '.$toto.' yy' ou "xx $toto yy"? BIen sûr, dans le cas où les xx et yy ne contienent pas de texte interprétable?

PS: je suis de retour de 15j de vacances :-p

Dernière modification par mathiasm (2006-04-10 16:20:11)

Hors ligne

Pied de page des forums

Propulsé par FluxBB

github twitter newsletter Faire un don Piwigo.org © 2002-2024 · Contact