トランザクションを作成 (または受信) するユーザーがいます。私が持っているトランザクション階層は複数テーブルの継承でありTransaction
、基本モデルとして、ユーザー (FK)、金額など、すべてのトランザクション タイプ間の共通フィールドが含まれています。Transaction
タイプ固有のモデルを拡張するいくつかのトランザクション タイプがあります。データ。
この例のために、私の問題を示す簡略化された構造を以下に示します。
from model_utils.managers import InheritanceManager
class User(models.Model):
pass
class Transaction(models.Model):
DEPOSIT = 'deposit'
WITHDRAWAL = 'withdrawal'
TRANSFER = 'transfer'
TYPES = (
(DEPOSIT, DEPOSIT),
(WITHDRAWAL, WITHDRAWAL),
(TRANSFER, TRANSFER),
)
type = models.CharField(max_length=24, choices=TYPES)
user = models.ForeignKey(User)
amount = models.PositiveIntegerField()
objects = InheritanceManager()
class Meta:
indexes = [
models.Index(fields=['user']),
models.Index(fields=['type'])
]
class Withdrawal(Transaction):
TYPE = Transaction.WITHDRAWAL
bank_account = models.ForeignKey(BankAccount)
class Deposit(Transaction):
TYPE = Transaction.DEPOSIT
card = models.ForeignKey(Card)
class Transfer(Transaction):
TYPE = Transaction.Transfer
recipient = models.ForeignKey(User)
class Meta:
indexes = [
models.Index(fields=['recipient'])
]
次に、継承されたモデルの.save()
メソッドで各トランザクションのタイプを設定します。これはすべて問題ありません。
ユーザーのトランザクションを取得したいときに問題が発生します。具体的には、基本モデル (トランザクション) ではなく、サブモデル インスタンス (預金、送金、および引き出し) が必要です。また、ユーザーが自分で作成したトランザクションと、受け取った送金の両方が必要です。前者の場合、私は素晴らしい作品django-model-utils
の素晴らしいを使用しIneritanceManager
ます。ただし、転送サブモデルの受信者 FK フィールドにフィルタリングを含めると、DB クエリが桁違いに増加します。
上記の図のように、Transactionuser
列と Transferrecipient
列にインデックスを配置しました。しかし、可能であれば、Transaction サブタイプのインデックスが必要になる可能性があるように思えました。以下に示すように、Transactiontype
フィールドにインデックスを配置してクエリに含めることで、この効果を達成しようとしましたが、これは効果がないようです。さらに、.select_related()
シリアライゼーションで必要なため、ユーザー オブジェクトに使用します。
クエリは次のように構成されています。
from django.db.models import Q
queryset = Transaction.objects.select_related(
'user',
'transfer__recipient'
).select_subclasses().filter(
Q(user=request.user) |
Q(type=Transaction.TRANSFER, transfer__recipient=request.user)
).order_by('-id')
だから私の質問は、クエリに を含めると、DB クエリに桁違いの違いがあるのはなぜTransfer.recipient
ですか? 私は何かを逃しましたか?私は何かばかげたことをしていますか?または、これをさらに最適化する方法はありますか?