Django - повторно использовать аннотированный счет - PullRequest
0 голосов
/ 16 января 2020

У меня есть модель, которая позволяет мне регистрировать ошибки с ха sh, который я генерирую, поэтому те же ошибки имеют тот же ха sh, поэтому я могу группировать и подсчитывать их. Модель выглядит примерно так.

class ErrorLog(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    date = models.DateTimeField(null=True, blank=True, db_index=True)
    log = models.TextField(blank=True, null=True)
    log_hash = models.CharField(max_length=255, blank=True, null=True)  

На мой взгляд, я выполняю следующий запрос для подсчета ошибок по га sh.

def get(self, request):
    qs = self.filter_queryset(self.get_queryset())
    total_errors = qs.count()

    qs = qs.values(
        'log_hash', 'log'
    ).annotate(
        error_count=Count('log_hash')
    ).annotate(
        percentage_of_occurrence=Concat(
            Cast(
                funcs.Round(
                    (F('error_count') / total_errors) * 100, 1
                ), CharField()
            ), Value('%')
        )
    )

Это работает как шарм, потому что я могу вернуть свои результаты точно так же, как я хочу.

"results": [
        {
            "error_count": 2,
            "percentage_of_occurrence": "50.0%",
            "log_hash": "8f7744ba51869f93ce990c67bd8d3544",
            "log": "Error 1"
        },
        {
            "error_count": 1,
            "percentage_of_occurrence": "25.0%",
            "log_hash": "de54a1e3be2cab4d04d8c61f538a71df",
            "log": "Error 2"
        },
        {
            "error_count": 1,
            "percentage_of_occurrence": "25.0%",
            "log_hash": "05988dc15543ef06e803a930923d11d4",
            "log": "Error 3"
        }
    ]

Здесь возникает проблема, это ДЕЙСТВИТЕЛЬНО медленно на большой таблице, поэтому после проверки сгенерированного SQL я обнаружил одну проблему. Я считаю 2 раза, один для получения error_count, а другой для вычисления percentage_of_occurrence.

SELECT `errorlog`.`log_hash`, `errorlog`.`log`, COUNT(`errorlog`.`log_hash`) AS `error_count`, 
((COUNT(`errorlog`.`log_hash`) / ) * 100) AS `percentage_of_occurrence` 
FROM `errorlog` 
GROUP BY `errorlog`.`log_hash`, `errorlog`.`log`
ORDER BY `error_count` DESC

Можно ли как-нибудь использовать первый счет для вычисления percentage_of_occurrence без придется снова считать? Кроме того, я не очень разбираюсь в SQL, но было бы лучше, если бы столбец log_hash был проиндексирован?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...