Projet

Général

Profil

Development #85107

agendas: requête lente

Ajouté par Pierre Ducroquet il y a 4 mois. Mis à jour il y a 4 mois.

Statut:
Fermé
Priorité:
Normal
Assigné à:
Catégorie:
-
Version cible:
-
Début:
24 décembre 2023
Echéance:
% réalisé:

0%

Temps estimé:
Patch proposed:
Non
Planning:
Non

Description

Vue sur la prod.

chrono=# explain analyze 
SELECT
  DISTINCT ON (extra_data_keys) jsonb_object_keys("agendas_booking"."extra_data") AS "extra_data_keys" 
FROM "agendas_booking" 
  INNER JOIN "agendas_event" ON ("agendas_booking"."event_id" = "agendas_event"."id") 
  INNER JOIN "agendas_agenda" ON ("agendas_event"."agenda_id" = "agendas_agenda"."id") 
  LEFT OUTER JOIN "agendas_virtualmember" ON ("agendas_agenda"."id" = "agendas_virtualmember"."real_agenda_id") 
WHERE (
  "agendas_event"."agenda_id" IN (SELECT U0."id" FROM "agendas_agenda" U0 WHERE U0."slug" = 'armentieres-david-baudin') 
OR "agendas_virtualmember"."virtual_agenda_id" IN (SELECT U0."id" FROM "agendas_agenda" U0 WHERE U0."slug" = 'armentieres-david-baudin')
) ORDER BY "extra_data_keys" ASC;

Les OR, c'est inbon. Les OR sur les jointures, c'est plusinbon.

L'écriture suivante est bien meilleure, et plus rapide d'un facteur 100 sur au moins un des tenants (12ms vs 1,3s).

chrono=# explain analyze
SELECT * FROM (
        SELECT
                DISTINCT ON (extra_data_keys) jsonb_object_keys("agendas_booking"."extra_data") AS "extra_data_keys" 
        FROM "agendas_booking" 
                INNER JOIN "agendas_event" ON ("agendas_booking"."event_id" = "agendas_event"."id")
                INNER JOIN "agendas_agenda" ON ("agendas_event"."agenda_id" = "agendas_agenda"."id")
        WHERE 
                agendas_agenda.slug = 'armentieres-david-baudin'
UNION
        SELECT
                DISTINCT ON (extra_data_keys) jsonb_object_keys("agendas_booking"."extra_data") AS "extra_data_keys" 
        FROM "agendas_booking" 
                INNER JOIN "agendas_event" ON ("agendas_booking"."event_id" = "agendas_event"."id")
                INNER JOIN "agendas_virtualmember" ON ("agendas_event"."agenda_id" = "agendas_virtualmember"."real_agenda_id")
        WHERE
                "agendas_virtualmember"."virtual_agenda_id" IN (SELECT U0."id" FROM "agendas_agenda" U0 WHERE U0."slug" = 'armentieres-david-baudin')
) foo ORDER BY  "extra_data_keys" ASC;

En effet, le OR sur la jointure impose une lecture complète des tables agendas_event et agendas_booking, alors qu'avec l'UNION on peut faire deux index scan à la place.

Historique

#1

Mis à jour par Pierre Ducroquet il y a 4 mois

  • Tracker changé de Support à Development
#2

Mis à jour par Robot Gitea il y a 4 mois

  • Statut changé de Nouveau à Solution proposée
  • Assigné à mis à Pierre Ducroquet

Pierre Ducroquet (pducroquet) a ouvert une pull request sur Gitea concernant cette demande :

#3

Mis à jour par Robot Gitea il y a 4 mois

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

Pierre Ducroquet (pducroquet) a commencé à travailler sur une pull request sur Gitea concernant cette demande :

#4

Mis à jour par Robot Gitea il y a 4 mois

  • Statut changé de En cours à Solution proposée
#5

Mis à jour par Robot Gitea il y a 4 mois

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

Benjamin Dauvergne (bdauvergne) a approuvé une pull request sur Gitea concernant cette demande :

#6

Mis à jour par Robot Gitea il y a 4 mois

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

Pierre Ducroquet (pducroquet) a mergé une pull request sur Gitea concernant cette demande :

#7

Mis à jour par Transition automatique il y a 4 mois

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

Mis à jour par Transition automatique il y a environ 2 mois

Automatic expiration

Formats disponibles : Atom PDF