モデル index リファレンス

Index クラスを利用すると、データベースのインデックスの作成が簡単になります。インデックスは、 Meta.indexes オプションを使用して追加できます。このドキュメントでは、 index options を含む Index の API リフェレンスを説明します。

ビルトインの indexes を参照する

Indexes は django.db.models.indexes で定義されていますが、簡単のため、django.db.models 内にインポートされています。from django.db import models を使用して、indexes を models.<IndexClass> として参照するのが標準的な慣習です。

Index オプション

class Index(*expressions, fields=(), name=None, db_tablespace=None, opclasses=(), condition=None, include=None)

データベース内にインデックス (B-Tree) を作成します。

expressions

Index.expressions

位置引数 *expressions を使用すると、式およびデータベース関数に対して関数インデックスを作成できます。

例:

Index(Lower("title").desc(), "pub_date", name="lower_title_date_idx")

この例は、title フィールドを小文字にした値の降順と、pub_date フィールドのデフォルトの昇順で、インデックスを作成します。

もう1つの例:

Index(F("height") * F("weight"), Round("weight"), name="calc_idx")

この例は、height および weight フィールドの積の結果と、weight を直近の整数に丸めた値で、インデックスを作成します。

*expressions を使用する場合、Index.name は必須です。

Oracle の制限

Oracle はインデックスから参照される関数を DETERMINISTIC とマークする必要があります。Django はこれを検証しませんが、 Oracle はエラーにします。つまり、 Random() のような関数は受け付けられません。

PostgreSQL の制限

PostgreSQL では、インデックス内で参照されている関数と演算子が IMMUTABLE としてマークされていなければなりません。Django はこのことを検証しませんが、PostgreSQL はエラーを起こします。これは、Concat() などの関数が受け入れられないことを意味します。

MySQL と MariaDB

関数インデックスは、MySQL < 8.0.13 および MariaDB ではサポートされていないため、無視されます。

fields

Index.fields

インデックスが必要なフィールド名のリストまたはタプル。

デフォルトでは、各カラムに対して昇順でインデックスが作成されます。カラムに対して降順のインデックスを定義するには、フィールド名の前にハイフンを追加します。

たとえば、Index(fields=['headline', '-pub_date'])(headline, pub_date DESC) を持つ SQL を作成します。

MariaDB

インデックスの順序は MariaDB < 10.8 ではサポートされていません。その場合は、降順のインデックスは普通のインデックスとして作成されます。

name

Index.name

インデックスの名前。name が与えられなかった場合、Django は名前を自動生成します。異なるデータベースとの互換性のため、インデックス名は最長30文字で、数字 (0-9) またはアンダースコア (_) から始めることはできません。

抽象基底クラス上の部分インデックス (partial index)

インデックスには、常にユニークな名前を指定しなければなりません。したがって、(name を含む) 属性に対して毎回完全に同じ値とともに Meta.indexes オプションがサブクラスに継承されるため、通常は抽象基底クラスには部分インデックスを指定できません。名前の衝突を回避するために、名前の一部に '%(app_label)s''%(class)s' を含めることができます。これらはそれぞれ、小文字のアプリラベルと具体的なモデルのクラス名に置換されます。たとえば、Index(fields=['title'], name='%(app_label)s_%(class)s_title_index') と指定できます。

db_tablespace

Index.db_tablespace

このインデックスに対して使用する データベースの tablespace の名前。単一フィールドのインデックスに対して、db_tablespace が提供されなかった場合、インデックスはフィールドの db_tablespace に作成されます。

Field.db_tablespace が指定されなかった場合 (または、インデックスが複数フィールドを使用している場合)、インデックスは、モデルの class Meta 内の db_tablespace オプションで指定されたtablespace 内に作成されます。もしどちらの tablespace も設定されていなかった場合には、インデックスはテーブルと同じ tablespace 内に作成されます。

参考

PostgreSQL 特有のインデックスの一覧については、 django.contrib.postgres.indexes を参照してください。

opclasses

Index.opclasses

このインデックスで使用する PostgreSQL の演算子クラス の名前。カスタム演算子クラスが必要な場合、インデックス内の各フィールドごとに1つ指定する必要があります。

たとえば、GinIndex(name='json_index', fields=['jsonfield'], opclasses=['jsonb_path_ops']) は、jsonb_path_ops を使用して jsonfield に gin インデックスを作成します。

opclasses はPostgreSQL以外のデータベースでは無視されます。

opclasses を使用する場合、Index.name が必要です。

condition

Index.condition

テーブルが非常に大きくて、ほとんどクエリが行のサブセットを対象としている場合、インデックスをそのサブセットに制限すると役に立つかもしれません。条件を Q として指定してください。たとえば、condition=Q(pages__gt=400) は、400ページ以上あるレコードにインデックスを作成します。

condition を使用する場合、Index.name が必要です。

PostgreSQL の制限

PostgreSQL では、条件内で参照されている関数が IMMUTABLE としてマークされていなければなりません。Django はこのことを検証しませんが、PostgreSQL はエラーを起こします。これは、 日時関連の関数Concat などの関数が受け入れられないことを意味します。日付を DateTimeField に保存している場合、datetime オブジェクトとの比較に tzinfo 引数を提供する必要があるかもしれません。そうしなければ、Django が lookups に対して行うキャスティングの結果、比較がミュータブルな関数になる可能性があるためです。

SQLite の制限

SQLite は、部分インデックスの構築方法に関して、制限が課されます

Oracle について

Oracle は部分インデックスをサポートしません。代わりに、関数インデックスを Case 式とともに使用することで、部分インデックスをエミュレーションできます。

MySQL と MariaDB

MySQL と MariaDB は条件付きインデックスサポートをしていないため、condition 引数は無視されます。

include

Index.include

非キーのカラムとしてカバーインデックスに含まれる、フィールド名のリストまたはタプル。これにより、含まれるフィールド (include) のみを select するクエリと、インデックスされたフィールド (fields) のみによってフィルタするクエリに対して、インデックスのみのスキャンが利用できるようになります。

例:

Index(name="covering_index", fields=["headline"], include=["pub_date"])

この例は、データをインデックスからのみ取得しながら、headline のフィルタリングと、pub_date の select を可能にします。

include を使うと、複数カラムのインデックスを使用するより小さなインデックスが生成されますが、非キーのカラムがソートやフィルタリングに使えないという欠点があります。

include は、PostgreSQL 以外のデータベースでは無視されます。

include を使用する場合、Index.name は必須です。

covering indexes に関する詳細については、PostgreSQL のドキュメントを参照してください。

PostgreSQL の制限

PostgreSQL は covering B-Tree および GiST インデックス をサポートします。PostgreSQL 14+ は covering SP-GiST インデックス もサポートします。

Back to Top