Bug #53151
closedTimeout 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.
Files
Updated by Valentin Deniaud about 5 years ago
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.
Updated by Benjamin Dauvergne about 5 years ago
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.
Updated by Benjamin Dauvergne about 5 years ago
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$` $
Updated by Benjamin Dauvergne about 5 years ago
- Copied from Développement #52854: Timeout sur /manage/users/xx/roles/ (quand on a 18 000 rôles) added
Updated by Emmanuel Cazenave (retour le 27 avril) about 5 years ago
- Related to Développement #53170: Compatibilité avec django-tables 2.1.1 added
Updated by Emmanuel Cazenave (retour le 27 avril) almost 5 years ago
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.
Updated by Benjamin Dauvergne almost 5 years ago
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).
Updated by Emmanuel Cazenave (retour le 27 avril) almost 5 years ago
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.
Updated by Benjamin Dauvergne almost 5 years ago
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().
Updated by Emmanuel Cazenave (retour le 27 avril) almost 5 years ago
- Status changed from Nouveau to En cours
- Assignee set to Emmanuel Cazenave (retour le 27 avril)
Updated by Emmanuel Cazenave (retour le 27 avril) almost 5 years ago
- File 0001-manager-speed-up-user-role-view-53151.patch 0001-manager-speed-up-user-role-view-53151.patch added
- Status changed from En cours to Solution proposée
- Patch proposed changed from No to Yes
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.
Updated by Emmanuel Cazenave (retour le 27 avril) almost 5 years ago
- File 0001-manager-speed-up-user-role-view-53151.patch 0001-manager-speed-up-user-role-view-53151.patch added
Un espace en moins dans un test.
Updated by Benjamin Dauvergne almost 5 years ago
- Status changed from Solution proposée to 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).
Updated by Emmanuel Cazenave (retour le 27 avril) almost 5 years ago
- Status changed from Solution validée to 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.
Updated by Emmanuel Cazenave (retour le 27 avril) almost 5 years ago
- File 0001-manager-paginate-user-role-view-53151.patch 0001-manager-paginate-user-role-view-53151.patch added
- Status changed from En cours to 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.
Updated by Benjamin Dauvergne almost 5 years ago
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.
Updated by Benjamin Dauvergne almost 5 years ago
- Status changed from Solution proposée to Solution validée
Je valide quand même ma remarque est un détail.
Updated by Emmanuel Cazenave (retour le 27 avril) almost 5 years ago
Ça passe aussi sans la méthode, je pousserai cette nouvelle version.
Updated by Emmanuel Cazenave (retour le 27 avril) almost 5 years ago
- Status changed from Solution validée to 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)
Updated by Frédéric Péters almost 5 years ago
- Status changed from Résolu (à déployer) to Solution déployée