Projet

Général

Profil

Bug #53151

Timeout sur /manage/users/xx/roles/ (quand on a 18 000 rôles)

Ajouté par Emmanuel Cazenave il y a environ 3 ans. Mis à jour il y a presque 3 ans.

Statut:
Fermé
Priorité:
Normal
Assigné à:
Catégorie:
-
Version cible:
-
Début:
15 avril 2021
Echéance:
% réalisé:

0%

Temps estimé:
Patch proposed:
Oui
Planning:
Non

Description

Pourtant il y a de la pagination, mais quand même plouf timeout.


Fichiers


Demandes liées

Lié à Authentic 2 - Development #53170: Compatibilité avec django-tables 2.1.1Nouveau15 avril 2021

Actions
Copié depuis Authentic 2 - Development #52854: Timeout sur /manage/users/xx/roles/ (quand on a 18 000 rôles)Rejeté08 avril 2021

Actions

Révisions associées

Révision f2cdd451 (diff)
Ajouté par Emmanuel Cazenave il y a presque 3 ans

manager: paginate user role view (#53151)

Historique

#1

Mis à jour par Valentin Deniaud il y a environ 3 ans

C'est peut-être quand même cette histoire de pagination qui est en cause, « The default Paginator wants to count the number of items, which might be an expensive operation for large QuerySets . In those cases, you can use LazyPaginator » https://django-tables2.readthedocs.io/en/latest/pages/pagination.html?highlight=singletableview#lazy-pagination.

#2

Mis à jour par Benjamin Dauvergne il y a environ 3 ans

Je pense que c'est ça, parce que la requête en dessous est complexe et le count() doit demander un scan complet.

PS: j'aurai bien répondu avec un screenshot de l'écran debug-toolbar SQL, mais là ça ne marche plus dans mon publik-devinst, je regarde pourquoi.

#3

Mis à jour par Benjamin Dauvergne il y a environ 3 ans

LazyPaginator n'a pas l'air disponible dans la version de django-tables2 qu'on utilise en prod (1.21.2), c'est introduit en 2.x :

$ grep LazyPa `dpkg -L python3-django-tables2 | grep py$`
$

#4

Mis à jour par Benjamin Dauvergne il y a environ 3 ans

  • Copié depuis Development #52854: Timeout sur /manage/users/xx/roles/ (quand on a 18 000 rôles) ajouté
#5

Mis à jour par Emmanuel Cazenave il y a environ 3 ans

#6

Mis à jour par Emmanuel Cazenave il y a presque 3 ans

Emmanuel Cazenave a écrit :

Pourtant il y a de la pagination

Mais en fait non, c'est désactivé (ne jamais croire sur parole ses collègues) :

class UserRolesView(HideOUColumnMixin, BaseSubTableView):

....

    @property
    def table_pagination(self):
        if self.is_ou_specified():
            return False
        return None

Mais même en activant la pagination ça timeout quand même .... retour à l'analyse sans pagination pour ne pas tout mélanger.

Tentative de mesurer les choses via la debugtoolbar qui s'enlise complètement dans du code récursif de django/template/base.py.

J’essaie avec mon couteau et dieu sait quoi, trafiquer OuUserRolesTable et voir ce que ça change. Il semble la colonne via soit très coûteuse à afficher :

    via = tables.TemplateColumn(
        '''{% for rel in record.via %}{{ rel.child }} {% if not forloop.last %}, {% endif %}{% endfor %}''',
        verbose_name=_('Inherited from'),
        orderable=False,
    )

Ce qui amène à s'intéresser au queryset qui est utilisé par la table :

qs = qs.prefetch_related(models.Prefetch('child_relation', queryset=rp_qs, to_attr='via'))

Mais je ne reproduis pas du tout les lenteurs en évaluant le queryset en dehors d'un template .... plouf l'impasse, j'en ai marre de pas comprendre.

#7

Mis à jour par Benjamin Dauvergne il y a presque 3 ans

Il faut juste regarder les requêtes SQL émises dans la debug-toolbar, tu devrais en voir une plus longue que les autres (si c'est bien une lenteur due à une requête SQL).

#8

Mis à jour par Emmanuel Cazenave il y a presque 3 ans

Benjamin Dauvergne a écrit :

Il faut juste regarder les requêtes SQL émises dans la debug-toolbar, tu devrais en voir une plus longue que les autres (si c'est bien une lenteur due à une requête SQL).

J'aurais du préciser mais non c'est pas du tout ça, temps global sur toutes les requêtes un peu long mais marginal par rapport au temps global.

#9

Mis à jour par Benjamin Dauvergne il y a presque 3 ans

Si tu as les instants de début des requêtes SQL et de fin de la requête Django on doit pouvoir dire si c'est le temps perdu est entre des requêtes ou après que toutes les requêtes aient été faite ? Ça pourrait pointer le bout de code python qui traite les résultats et est un peu lent.

Aussi il me semble que django-tables2 utilise mal la pagination SQL (i.e. il fait list(qs)[debut:fin] au lieu de qs[debug:fin]), il faudrait vérifier qu'il ne récupère pas tous les résultats ça se voir dans le SQL si tu vois des LIMIT/OFFSET ou pas; en fait je ne sais pas trop si le temps rapporté pour une requête SQL est celui de la récupération totale des résultats ou seulement de la requête initiale avant récupération des lignes (ça peut être trompeur) via cursor.fetchmany().

#11

Mis à jour par Emmanuel Cazenave il y a presque 3 ans

  • Statut changé de Nouveau à En cours
  • Assigné à mis à Emmanuel Cazenave
#12

Mis à jour par Emmanuel Cazenave il y a presque 3 ans

Les templates dans dans les templates c'est pas bon pour la perf apparemment. Avec 5000 rôles je passe de 28 à 6 secondes avec ce patch.

#14

Mis à jour par Benjamin Dauvergne il y a presque 3 ans

  • Statut changé de Solution proposée à Solution validée

Si ça te paraît suffisant (mais ça m'intéresse de savoir comment ça peut bouffer 22 secondes de plus quand c'est paginé et que donc ça ne s'exécute que quelques dizaines de fois).

#15

Mis à jour par Emmanuel Cazenave il y a presque 3 ans

  • Statut changé de Solution validée à En cours

Ça n'est pas paginé, d'où le gain. Mais en testant sur 20000 rôles et pas 5000, ça remonte à 60 secondes, inutilisable.

Je vais regarder pour la pagination.

#16

Mis à jour par Emmanuel Cazenave il y a presque 3 ans

Dans la série faire beaucoup de bruit pour rien, j'étais persuadé d'avoir testé la pagination et constaté que ça ramait encore à fond. Mais là je teste à nouveau avec ce bête patch sur 20000 rôles et ça répond dans des temps tout à fait acceptable. J'ai du m'emmêler les pinceaux la première fois.

#17

Mis à jour par Benjamin Dauvergne il y a presque 3 ans

Emmanuel Cazenave a écrit :

Dans la série faire beaucoup de bruit pour rien, j'étais persuadé d'avoir testé la pagination et constaté que ça ramait encore à fond. Mais là je teste à nouveau avec ce bête patch sur 20000 rôles et ça répond dans des temps tout à fait acceptable. J'ai du m'emmêler les pinceaux la première fois.

Est-ce que ça marche aussi simplement en enlevant la méthode ? Parce que c'est bizarre de passer de False/None à True.

#18

Mis à jour par Benjamin Dauvergne il y a presque 3 ans

  • Statut changé de Solution proposée à Solution validée

Je valide quand même ma remarque est un détail.

#19

Mis à jour par Emmanuel Cazenave il y a presque 3 ans

Ça passe aussi sans la méthode, je pousserai cette nouvelle version.

#20

Mis à jour par Emmanuel Cazenave il y a presque 3 ans

  • Statut changé de Solution validée à Résolu (à déployer)
commit f2cdd451dad7c9ed2430a7c99483da9aef29fae6
Author: Emmanuel Cazenave <ecazenave@entrouvert.com>
Date:   Mon May 10 14:22:14 2021 +0200

    manager: paginate user role view (#53151)
#21

Mis à jour par Frédéric Péters il y a presque 3 ans

  • Statut changé de Résolu (à déployer) à Solution déployée

Formats disponibles : Atom PDF