3

どちらがパフォーマンスに優れていますか?

私たちは製品のスライスを取ります。一括更新が不可能になります。

products = Product.objects.filter(featured=True).order_by("-modified_on")[3:]

for product in products:
  product.featured = False
  product.save()

または(無効)

for product in products.iterator():
  product.update(featured=False)

私は次のようにQuerySetのinステートメントも試しました。

Product.objects.filter(pk__in=products).update(featured=False)

この行はSQLiteで正常に機能します。ただし、MySQLの例外に続いて発生します。だから、私はそれを使うことができませんでした。

DatabaseError:(1235、「このバージョンのMySQLはまだ「LIMIT&IN / ALL / ANY /SOMEサブクエリ」をサポートしていません」)

編集:また、iterator()メソッドはクエリを再評価します。したがって、パフォーマンスに悪影響を及ぼします。

4

2 に答える 2

2

@Chris Prattがコメントで指摘したように、オブジェクトにはupdateメソッドがないため、2番目の例は無効です。最初の例では、各オブジェクトを更新する必要があるため、results+1に等しいクエリが必要になります。あなたが1000の製品を持っているならば、それは本当に費用がかかるかもしれません。理想的には、可能であればこれをより固定費に削減したいと思います。

これは別の質問と同様の状況です:
Django:スライスが取得されるとクエリを更新できません

そうは言っても、少なくとも2つのクエリでそれを行う必要がありますが、LIMITの作成方法については少しこっそりする必要があります...

複雑なクエリにQオブジェクトを使用する:

# get the IDs we want to exclude
products = Product.objects.filter(featured=True).order_by("-modified_on")[:3]
# flatten them into just a list of ids
ids = products.values_list('id', flat=True)

# Now use the Q object to construct a complex query
from django.db.models import Q
# This builds a list of "AND id NOT EQUAL TO i"
limits = [~Q(id=i) for i in ids]
Product.objects.filter(featured=True, *limits).update(featured=False)
于 2012-05-21T19:57:36.970 に答える