我有一个模型,该模型允许我使用生成的哈希记录错误,因此相同的错误具有相同的哈希,因此我可以对它们进行分组和计数。该模型看起来像这样。
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)
在我看来,我执行以下查询以按哈希计数错误。
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之后,我看到了一个问题。我数了两次,一次是获取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
列建立索引会更好吗?