2016-12-09 2 views
1

В приложении Django у меня есть набор компаний с историей действий, которые были выполнены в прошлом. Я получить эти операции со следующим, возмутительно дорогой QuerySet:Как оптимизировать этот конкретный Queryset?

class Company(AbstractBaseUser, PermissionsMixin): 
    ... 
    def get_transactions_history(self): 
     return Transaction.objects.filter(sponsorship__campaign__shop__company=self) 

Очевидно, что это приводит к большому количеству JOIN инструкций от ОРМА и поскольку число Transactions может быстро увеличиваться, пропускная способность на дб также взрывается из-за этого Queryset.

Если предположить, что нет ярлыка между Transaction и Company, кроме цепочки через Sponsorship, Campaign и Shop как открытой выше, как бы вы оптимизировать QuerySet, не касаясь в схеме базы данных?

+0

Если конечный результат транзакции - отношения компании - это как «сквозная», использование «триггера» для создания теневой копии только «transaction_id» и «company_id» всякий раз, когда создается транзакция, кажется логичным для меня. – Anzel

+0

. вещь, близкая к оптимизации, будет 'shop__company_id = self.id', но я не думаю, что это помогло бы многим – Sayse

+0

@Sayse, как бы' company_id = self.id' улучшило производительность? Это потому, что сравнение двух целых чисел быстрее, чем сравнение двух объектов? – Buddyshot

ответ

1

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

Theres cached_property

@cached_property 
def history(self): 

Что делает именно то, что он говорит, что это.

В противном случае вам нужно разделить это в recent_history что сростков в QuerySet

.filter(...)[:10] 

или пагинацию

0

Если вы не можете оптимизировать его на уровне SQL, то есть не так много вы можете сделать на Очевидно, что уровень ОРМ.

Смежные вопросы