У меня есть модель, которая позволяет мне регистрировать ошибки с ха 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
был проиндексирован?