Есть ли преимущества в производительности, если разделить модель / таблицу Django на две модели / таблицы? - PullRequest
1 голос
/ 14 октября 2011

В SO вопрос 7531153 , я спросил, как правильно разделить модель Django на две - используя наследование нескольких таблиц Django или явно указав OneToOneField.

Исходя из комментария Люка Снерингера , мне любопытно, выиграет ли производительность от деления модели на две части.

Причина, по которой я думал о разделении модели на две части, заключается в том, что у меня есть некоторые поля, которые всегда будут заполняться, в то время как есть другие поля, которые обычно будут пустыми (до тех пор, пока проект не будет закрыт).

Есть ли прирост производительности от помещения обычно пустых полей, таких как actual_completion_date и actual_project_costs, в отдельную модель / таблицу в Django?

Разделить на две модели

class Project(models.Model):
    project_number = models.SlugField(max_length=5, blank=False,
            primary_key=True)
    budgeted_costs = models.DecimalField(max_digits=10, decimal_places=2)
    submitted_on = models.DateField(auto_now_add=True)

class ProjectExtendedInformation(models.Model):
    project = models.OneToOneField(CapExProject, primary_key=True)
    actual_completion_date = models.DateField(blank=True, null=True)
    actual_project_costs = models.DecimalField(max_digits=10, decimal_places=2,
            blank=True, null=True)

Ответы [ 2 ]

7 голосов
/ 14 октября 2011

На самом деле, совсем наоборот.Каждый раз, когда задействованы несколько таблиц, потребуется SQL JOIN, который по своей сути медленнее для базы данных, чем простой запрос SELECT.Тот факт, что поля являются пустыми, не имеет никакого значения с точки зрения производительности, так или иначе.

В зависимости от размера таблицы и количества столбцов может быть быстрее выбрать только подмножество полей, которые вынужно взаимодействовать, но в Django это достаточно просто с помощью метода only:

Project.objects.only('project_number', 'budgeted_costs', 'submitted_on')

, который производит нечто похожее на:

SELECT ('project_number', 'budgeted_costs', 'submitted_on') FROM yourapp_project;

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

6 голосов
/ 14 октября 2011

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

Присоединения неплохие. Особенно в вашем случае объединение будет быстрее, если у вас есть все строки в одной таблице и намного меньше строк в другой. Я много работал с базами данных, и в большинстве случаев можно догадаться, будет ли объединение лучше или хуже. Даже полное сканирование таблицы лучше, чем использование индекса во многих случаях. Вам нужно посмотреть на ОБЪЯСНЕНИЯ, если производительность вызывает беспокойство, и по возможности профилировать работу с БД (я знаю, что Oracle поддерживает это). Но прежде чем производительность станет проблемой, я предпочитаю более быструю разработку.

У нас есть таблица в Django с 5M строками. И нам нужен был столбец, который был бы не нулевым только для 1К строк. Простое изменение таблицы заняло бы полдня. Восстановление с нуля также занимает несколько часов. Мы решили сделать отдельную модель.

Я был на лекции по доменно-ориентированному проектированию, в которой автор объяснял, что важно, особенно при разработке нового приложения, разделять модели, чтобы не объединять все в одном классе.

Допустим, у вас есть класс CargoAircraft и PassengerAircraft. Так заманчиво поместить их в один класс и работать "без проблем", не так ли? Но взаимодействия с ними (планирование, резервирование, расчеты веса или мощности) совершенно разные .

Итак, помещая все в один класс, вы заставляете себя связывать предложения IF в каждом методе, дополнительные методы в Manager, усложнять отладку, большие таблицы в БД. В основном вы заставляете себя тратить больше времени на разработку ради чего? Только для двух вещей: 1) меньше объединений 2) меньше имен классов.

Если вы разделяете классы, дела идут намного проще:

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

следовательно, более быстрое развитие.

...