Bug #53151
Timeout sur /manage/users/xx/roles/ (quand on a 18 000 rôles)
0%
Description
Pourtant il y a de la pagination, mais quand même plouf timeout.
Fichiers
Demandes liées
Révisions associées
Historique
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.
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.
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$` $
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é
Mis à jour par Emmanuel Cazenave il y a environ 3 ans
- Lié à Development #53170: Compatibilité avec django-tables 2.1.1 ajouté
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.
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).
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.
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().
Mis à jour par Emmanuel Cazenave il y a presque 3 ans
- Statut changé de Nouveau à En cours
- Assigné à mis à Emmanuel Cazenave
Mis à jour par Emmanuel Cazenave il y a presque 3 ans
- Fichier 0001-manager-speed-up-user-role-view-53151.patch 0001-manager-speed-up-user-role-view-53151.patch ajouté
- Statut changé de En cours à Solution proposée
- Patch proposed changé de Non à Oui
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.
Mis à jour par Emmanuel Cazenave il y a presque 3 ans
- Fichier 0001-manager-speed-up-user-role-view-53151.patch 0001-manager-speed-up-user-role-view-53151.patch ajouté
Un espace en moins dans un test.
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).
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.
Mis à jour par Emmanuel Cazenave il y a presque 3 ans
- Fichier 0001-manager-paginate-user-role-view-53151.patch 0001-manager-paginate-user-role-view-53151.patch ajouté
- Statut changé de En cours à Solution proposée
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.
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.
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.
Mis à jour par Emmanuel Cazenave il y a presque 3 ans
Ça passe aussi sans la méthode, je pousserai cette nouvelle version.
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)
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
manager: paginate user role view (#53151)