Django qs аннотированное поле дубликат sql
У меня есть такой запрос в django
qs_match_annotation = "some sub query"
qs = qs.annotate(match=qs_match_annotation)
qs = qs.filter(match__gt=0)
qs = qs.order_by("-match")
sql, сгенерированный для qs_match_annotation, снова записывается в order_by вместо того, чтобы просто сгенерировать
ORDER BY match DESC
он снова пишет весь подзапрос
как это исправить?
как исправить такую вещь?
Нет. Это одна из неэффективностей Django ORM, которая (возможно) со временем будет исправлена. Насколько я знаю, это также не стандартный SQL, что вы можете ссылаться на колонку в запросе SELECT
: некоторые диалекты (возможно) не позволяют этого, и да, мне это тоже показалось глупым.
Но обычно это очень незначительно влияет на производительность, потому что обычно большая часть усилий тратится на получение данных.
Если вам не нужен match
в запросе SELECT
, вы можете использовать .alias(…)
[Django-doc]:
qs = qs.alias(match=qs_match_annotation).filter(match__gt=0).order_by('-match')
Тогда, по крайней мере, он не будет дублироваться в предложении SELECT.
Так что, очевидно, это проблема sql, а не django
Вы не можете иметь псевдоним в операторе were.
вероятно, псевдоним не будет оценен в части where выполнения запроса.
Итак, бд не может использовать колонку, которой у нее нет, и в результате запрещает ее
Значит ли это, что псевдоним sql будет оцениваться более одного раза? Нет, зависит от движка оптимизации базы данных, но скорее всего нет, единственный недостаток здесь - это написание одного и того же sql более одного раза, но это никак не влияет на производительность
Кроме того, если вам не важно возвращаемое значение совпадения
используйте qs.alias(), чтобы предотвратить запись туда же