Каковы недостатки упорядочения по умолчанию с помощью PK в Django?

Модели Django теперь поддерживают упорядочение по умолчанию с помощью Meta.ordering. Каковы недостатки использования ordering = ["pk"] в моей базовой модели?

В частности, мне интересно, как это повлияет на производительность. В документах Django есть неопределенное предупреждение о том, что это может повлиять на производительность:

Заказ не является бесплатным; каждое поле для заказа - это операция, которую должна выполнить база данных. Если у модели есть порядок по умолчанию (Meta.ordering) и он вам не нужен, удалите его из набора запросов, вызвав order_by() без параметров.

Но действительно ли упорядочивание по первичному ключу обходится дорого, если я использую Postgres в качестве базы данных?

Я бы сказал, что установка ordering = ['pk'] в вашей базовой модели может привести к некоторым затратам в PostgreSQL, если мы имеем дело с проектом с большими запросами.

Одним из таких случаев является то, что PostgreSQL, возможно, придется сортировать запросы, которые не требуют упорядочивания, например ChildModel.objects.all(), ChildModel.objects.count(), и т.д. что может привести к снижению скорости выполнения больших запросов. Как указано в документации, заказ не является бесплатным и оплачивается отдельно.

Таким образом, установка ordering = ['pk'] для базовой модели заставит все модели, которые наследуются от нее, наследовать этот порядок, за исключением того, что вы переопределяете Meta.ordering для моделей, для которых вы хотите установить порядок по умолчанию. Это может привести к снижению производительности и замедлению выполнения запросов. Таким образом, скорость может быть проблемой для крупных проектов.

Кроме того, если базовая модель использует UUID в качестве pk или других непоследовательных первичных ключей, Meta.ordering = ['pk'] может привести к недетерминированному упорядочению.

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

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

Однако выполнение запросов займет немного больше времени, а для запросов, в которых вы разбиваете результат на страницы, это может оказать большее влияние: если вы попросите "дать мне первые 50 строк", база данных может составить план запроса и просто выдать вам результаты пока у него не будет 50 таких строк. Если вы запрашиваете первые 50 строк в определенном порядке, то ему самому по себе не нужно определять полный результирующий набор, но тогда он должен оценивать определенные операции в определенном порядке, что, конечно, может замедлить обработку.

Как бы то ни было, я не думаю, что в этом есть что-то особенное: если вы разбиваете результаты на страницы и не упорядочиваете их, это может привести к несогласованному упорядочению различных запросов, так что в любом случае это не очень хорошая идея.

Вернуться на верх