Djangoクエリセットの最適化-注釈付きフィールドの選択を防止します

radoh

次のモデルがあるとしましょう:

class Invoice(models.Model):
    ...

class Note(models.Model):
    invoice = models.ForeignKey(Invoice, related_name='notes', on_delete=models.CASCADE)
    text = models.TextField()

いくつかのメモがある請求書を選択したいと思います私はこれをannotate/のExistsように使用して書きます:

Invoice.objects.annotate(
    has_notes=Exists(Note.objects.filter(invoice_id=OuterRef('pk')))
).filter(has_notes=True)

これは十分に機能し、メモ付きの請求書のみをフィルタリングします。ただし、この方法では、クエリ結果フィールドが表示されます。これは不要であり、パフォーマンスが低下します(SQLはサブクエリを2回実行する必要があります)。

私はこれを次のextra(where=)ように書くことができることに気づきました

Invoice.objects.extra(where=['EXISTS(SELECT 1 FROM note WHERE invoice_id=invoice.id)'])

これは理想的なSQLになりますが、一般にextra/ rawSQLを使用することはお勧めしませんこれを行うためのより良い方法はありますか?

martin.macko.47

.values()クエリセットメソッドを使用して、SELECT句からアノテーションを削除できます。問題.values()は、スキップする名前の代わりに保持するすべての名前を列挙する必要が.values()あり、モデルインスタンスの代わりに辞書返すことです

Djangoは内部的に、削除されたアノテーションを追跡しQuerySet.query.annotation_select_maskます。したがって、これを使用して、Djangoにどの注釈をスキップするかを指示できます.values()

class YourQuerySet(QuerySet):
    def mask_annotations(self, *names):
        if self.query.annotation_select_mask is None:
            self.query.set_annotation_mask(set(self.query.annotations.keys()) - set(names))
        else:
            self.query.set_annotation_mask(self.query.annotation_select_mask - set(names))
        return self

次に、次のように書くことができます。

invoices = (Invoice.objects
  .annotate(has_notes=Exists(Note.objects.filter(invoice_id=OuterRef('pk'))))
  .filter(has_notes=True)
  .mask_annotations('has_notes')
)

has_notesSELECT句をスキップしても、フィルタリングされた請求書インスタンスを取得します。結果のSQLクエリは次のようになります。

SELECT invoice.id, invoice.foo FROM invoice
WHERE EXISTS(SELECT note.id, note.bar FROM notes WHERE note.invoice_id = invoice.id) = True

これannotation_select_maskは内部DjangoAPIであり、将来のバージョンで警告なしに変更される可能性があることに注意してください。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

Djangoクエリセットの反復の最適化

分類Dev

Djangoクエリセット関連の比較の最適化

分類Dev

Djangoクエリセットの注釈、選択肢のある文字フィールド、および表示値を取得しようとしています

分類Dev

ZF2注釈付きの教義:複数選択フィールドをクリアする方法は?

分類Dev

Django Rest Framework:クエリセットの注釈付きフィールドの出力形式を変更する

分類Dev

注釈プロセッサに注釈付きオブジェクトからクラスのフィールドを取得します

分類Dev

Django ORMのクエリでグループ化された注釈付きフィールドの合計の最大値を計算しますか?

分類Dev

注釈付きのDjangoクエリセット、なぜGROUP BYがすべてのフィールドに適用されるのですか?

分類Dev

IMDBデータセットのSQLクエリ最適化

分類Dev

行の日付フィールドに基づいて、前の日曜日にDjangoクエリセットに注釈を付けます

分類Dev

Djangoのフィールド値の対数でクエリセットに注釈を付ける

分類Dev

Djangoは、m2mからモデルまでのフィールドごとにクエリセットに注釈を付けます

分類Dev

ループ用にDjangoクエリセットを最適化する

分類Dev

djangoでの大きなクエリセット/コンテキストの最適化

分類Dev

Djangoクエリセットの最適化:フィルターを使用した_setの逆ルックアップ

分類Dev

注釈付きのdjangoクエリセットがシリアル化中に無視されます

分類Dev

Django 1.10.7 ORMは、多対多のフィールドにわたる条件付きカウントでクエリに注釈を付けます

分類Dev

Djangoクエリセット。1つのクエリでさまざまなフィールドに注釈を付ける

分類Dev

Djangoクエリセット。1つのクエリでさまざまなフィールドに注釈を付ける

分類Dev

大きなデータセット上のMySQLのクエリの最適化

分類Dev

Guiceはどのようにして注釈付きフィールドに入力しますか

分類Dev

大きな結果セットを使用したクエリの最適化

分類Dev

複数のフィールドを使用してカウントでDjangoクエリセットに注釈を付ける

分類Dev

関連するモデルからの情報の新しいフィールドでクエリセットに注釈を付ける方法は?

分類Dev

春ブートアプリケーションで@value注釈付きフィールド上の制約を強制します

分類Dev

Django-SQLクエリの最適化

分類Dev

Djangoクエリの最適化

分類Dev

クエリの最適化:列が別のセットの最大である結果セットの最小を選択します

分類Dev

注釈付きのすべてのフィールドをプルします(別のオブジェクト内のフィールドと内部クラスのフィールドを含む)

Related 関連記事

  1. 1

    Djangoクエリセットの反復の最適化

  2. 2

    Djangoクエリセット関連の比較の最適化

  3. 3

    Djangoクエリセットの注釈、選択肢のある文字フィールド、および表示値を取得しようとしています

  4. 4

    ZF2注釈付きの教義:複数選択フィールドをクリアする方法は?

  5. 5

    Django Rest Framework:クエリセットの注釈付きフィールドの出力形式を変更する

  6. 6

    注釈プロセッサに注釈付きオブジェクトからクラスのフィールドを取得します

  7. 7

    Django ORMのクエリでグループ化された注釈付きフィールドの合計の最大値を計算しますか?

  8. 8

    注釈付きのDjangoクエリセット、なぜGROUP BYがすべてのフィールドに適用されるのですか?

  9. 9

    IMDBデータセットのSQLクエリ最適化

  10. 10

    行の日付フィールドに基づいて、前の日曜日にDjangoクエリセットに注釈を付けます

  11. 11

    Djangoのフィールド値の対数でクエリセットに注釈を付ける

  12. 12

    Djangoは、m2mからモデルまでのフィールドごとにクエリセットに注釈を付けます

  13. 13

    ループ用にDjangoクエリセットを最適化する

  14. 14

    djangoでの大きなクエリセット/コンテキストの最適化

  15. 15

    Djangoクエリセットの最適化:フィルターを使用した_setの逆ルックアップ

  16. 16

    注釈付きのdjangoクエリセットがシリアル化中に無視されます

  17. 17

    Django 1.10.7 ORMは、多対多のフィールドにわたる条件付きカウントでクエリに注釈を付けます

  18. 18

    Djangoクエリセット。1つのクエリでさまざまなフィールドに注釈を付ける

  19. 19

    Djangoクエリセット。1つのクエリでさまざまなフィールドに注釈を付ける

  20. 20

    大きなデータセット上のMySQLのクエリの最適化

  21. 21

    Guiceはどのようにして注釈付きフィールドに入力しますか

  22. 22

    大きな結果セットを使用したクエリの最適化

  23. 23

    複数のフィールドを使用してカウントでDjangoクエリセットに注釈を付ける

  24. 24

    関連するモデルからの情報の新しいフィールドでクエリセットに注釈を付ける方法は?

  25. 25

    春ブートアプリケーションで@value注釈付きフィールド上の制約を強制します

  26. 26

    Django-SQLクエリの最適化

  27. 27

    Djangoクエリの最適化

  28. 28

    クエリの最適化:列が別のセットの最大である結果セットの最小を選択します

  29. 29

    注釈付きのすべてのフィールドをプルします(別のオブジェクト内のフィールドと内部クラスのフィールドを含む)

ホットタグ

アーカイブ