Projet

Général

Profil

0001-performance-use-a-distinct-query-for-statistics-X-ax.patch

Pierre Ducroquet, 27 septembre 2022 13:11

Télécharger (4,21 ko)

Voir les différences:

Subject: [PATCH] performance: use a distinct query for statistics X axis
 (#69606)

 src/authentic2/apps/journal/models.py |  8 +++++++-
 src/authentic2/apps/journal/utils.py  | 15 +++++++++------
 src/authentic2/journal_event_types.py |  4 ++--
 3 files changed, 18 insertions(+), 9 deletions(-)
src/authentic2/apps/journal/models.py
136 136
            qs = qs.filter(timestamp__gte=start)
137 137
        if end:
138 138
            qs = qs.filter(timestamp__lte=end)
139
        x_interval_qs = qs
139 140

  
140 141
        values = [group_by_time]
141 142
        if group_by_time != 'timestamp':
......
156 157

  
157 158
        qs = qs.values(*values)
158 159
        qs = qs.annotate(count=Count('id'))
159
        return qs.order_by(group_by_time)
160
        x_interval = x_interval_qs.aggregate(min=Trunc(Min("timestamp"), kind=group_by_time, output_field=models.DateField()), max=Trunc(Max("timestamp"), kind=group_by_time, output_field=models.DateField()))
161

  
162
        return (qs.order_by(group_by_time), x_interval)
160 163

  
161 164
    def __repr__(self):
162 165
        return '<EventTypeDefinition %r %s>' % (self.name, self.label)
......
431 434
        verbose_name = _('event')
432 435
        verbose_name_plural = _('events')
433 436
        ordering = ('timestamp', 'id')
437
        index_together = [
438
            ("type", "timestamp"),
439
        ]
434 440

  
435 441

  
436 442
class EventCursor(str):
src/authentic2/apps/journal/utils.py
48 48
    }
49 49
    default_y_label = _('None')
50 50

  
51
    def __init__(self, qs, time_interval):
51
    def __init__(self, qs, time_interval, x_interval = None):
52 52
        self.time_interval = time_interval
53
        self.x_labels = self.build_x_labels(qs)
53
        self.x_labels = self.build_x_labels(qs, interval_qs)
54 54
        self._x_labels_indexes = {label: i for i, label in enumerate(self.x_labels)}
55 55
        self.series = {}
56 56
        self.y_labels = []
......
58 58
    def set_y_labels(self, y_labels):
59 59
        self.y_labels[:] = y_labels
60 60

  
61
    def build_x_labels(self, qs):
61
    def build_x_labels(self, qs, x_interval = None):
62 62
        if self.time_interval == 'timestamp':
63 63
            return list(qs.distinct().values_list(self.time_interval, flat=True))
64 64

  
65
        aggregate = qs.aggregate(min=Min(self.time_interval), max=Max(self.time_interval))
66
        if not aggregate['min']:
67
            return []
65
        if x_interval is not None:
66
            aggregate = x_interval
67
        else:
68
            aggregate = qs.aggregate(min=Min(self.time_interval), max=Max(self.time_interval))
69
            if not aggregate['min']:
70
                return []
68 71

  
69 72
        min_date, max_date = aggregate['min'].date(), aggregate['max'].date()
70 73
        if self.time_interval == 'day':
src/authentic2/journal_event_types.py
68 68
        elif service:
69 69
            which_references = service
70 70

  
71
        qs = cls.get_statistics(
71
        qs, x_interval = cls.get_statistics(
72 72
            group_by_time=group_by_time,
73 73
            group_by_field='how',
74 74
            which_references=which_references,
......
76 76
            start=start,
77 77
            end=end,
78 78
        )
79
        stats = Statistics(qs, time_interval=group_by_time)
79
        stats = Statistics(qs, time_interval=group_by_time, x_interval=x_interval)
80 80

  
81 81
        for stat in qs:
82 82
            stats.add(x_label=stat[group_by_time], y_label=stat['how'], value=stat['count'])
83
-