-
Notifications
You must be signed in to change notification settings - Fork 26
Statistiques: Correction du nombre de membres dans les exports #4622
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
0f8ce18 to
5557aab
Compare
f61a4b1 to
29e4720
Compare
itou/metabase/tables/utils.py
Outdated
| def get_first_membership_join_date(memberships): | ||
| memberships = list(memberships.all()) | ||
| # We have to do all this in python to benefit from prefetch_related. | ||
| # Prefetched memberships are sorted by -joined_at |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Le order_by() pourrais être modifié ou supprimé que personne irai voir dans cette fonction, donc pas super à l'aise d'avoir cette supposition.
Par contre le tri est effectivement coûteux pour rien, ce qu'on cherche au final c'est min(joined_at) donc soit le faire en python ici, ou alors peut-être essayer en forçant une sous-requête avec un .annotate(date_inscription=SubQuery(...)).
Le coup de la sous requête pourrais d'ailleurs peut-être aussi être essayer pour le active_memberships plutôt que prefetch 🤷, y a moyen que ça soit pas pire niveaux perf et ça nous éviterais du code 🤷.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alors de manière assez incompréhensible, quand j'ai essayé de faire un annotate à la place, c'était plus long (pour les entreprises) ou infiniment trop long (pour les organisations).
Je vais ré-essayer d'écrire les annotations pour essayer de comprendre ce qui pose problème.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ce que tu me dis me choque pas pour un .annotate(date_inscription=Min("members__joined_at")) car il va y avoir un JOIN de la mort avec les utilisateurs, mais un .annotate(date_inscription=SubQuery(CompanyMembership.objects.active().filter(company=OuterRef("pk").annotate(min=Min("joined_at").values("min")))) (pas sûr des parenthèses mais tu vois l'idée 😁) devrait je pense plutôt bien s'en sortir et ne pas être dépendant des autres annotations ou de la requête de base.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
first_membership_join_date=Subquery(
CompanyMembership.objects.filter(company_id=OuterRef("id"))
.values("company_id")
.annotate(min=Min("joined_at"))
.values("min")
),
active_membership_count=Subquery(
CompanyMembership.objects.filter(company_id=OuterRef("id"))
.active()
.values("company_id")
.annotate(count=Count("pk"))
.values("count")
),
last_login=Subquery(
CompanyMembership.objects.filter(company_id=OuterRef("id"))
.values("company_id")
.annotate(last_login=Max("user__last_login"))
.values("last_login")
),
Ca fonctionne, mais c'est beaucoup plus long (similaire à l'annotation directe)
Je laisse comme c'est ici du coup :)
6a5125c to
716a752
Compare
716a752 to
6a242df
Compare
🤔 Pourquoi ?
Pour avoir le bon nombre de membres.
Pour les organisations, il est beaucoup trop coûteux de faire une annotation, donc je suis resté sur un calcul python avec un prefretch plus restrictif. (j'ai arrêté après 300 orga exportées sur 8600 en plus d'une minute...)
populate_companiespopulate_organizationsIl faut éviter les annotations sur les memberships / members qui sont très coûteuse (aucune idée de pourquoi 🤷)
🍰 Comment ?
🚨 À vérifier
🏝️ Comment tester
💻 Captures d'écran