Référence des index de modèle

Les classes d’index facilitent la création d’index de base de données. Elles peuvent être ajoutées avec l’option Meta.indexes. Ce document détaille les références d’API de Index ce qui inclut les options d’index.

Référencement des index intégrés

Les index sont définis dans django.db.models.indexes, mais par commodité ils sont importés dans django.db.models. La convention standard est d’utiliser from django.db import models et de se référer aux index avec models.<IndexClass>.

Options d”Index

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

Crée un index (B-Tree) dans la base de données.

expressions

Index.expressions
New in Django 3.2.

Positional argument *expressions allows creating functional indexes on expressions and database functions.

Par exemple :

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

creates an index on the lowercased value of the title field in descending order and the pub_date field in the default ascending order.

Another example:

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

creates an index on the result of multiplying fields height and weight and the weight rounded to the nearest integer.

Index.name is required when using *expressions.

Restrictions on Oracle

Oracle requires functions referenced in an index to be marked as DETERMINISTIC. Django doesn’t validate this but Oracle will error. This means that functions such as Random() aren’t accepted.

Restrictions pour PostgreSQL

PostgreSQL requires functions and operators referenced in an index to be marked as IMMUTABLE. Django doesn’t validate this but PostgreSQL will error. This means that functions such as Concat() aren’t accepted.

MySQL et MariaDB

Functional indexes are ignored with MySQL < 8.0.13 and MariaDB as neither supports them.

fields

Index.fields

Une liste ou un tuple de noms de champs sur lesquels l’index doit porter.

Par défaut, les index sont créés avec un tri croissant sur chaque colonne. Pour définir un index avec un tri décroissant sur une certaine colonne, ajoutez un tiret devant le nom du champ.

Par exemple, Index(fields=['headline', '-pub_date']) produit un code SQL contenant (headline, pub_date DESC). Le tri dans les index n’est pas géré par MySQL. Dans ce cas, un index avec tri décroissant est traité comme un index normal.

name

Index.name

Le nom de l’index. Si name n’est pas fourni, Django va générer automatiquement un nom. Par compatibilité avec les différentes bases de données, les noms d’index ne peuvent pas être plus longs que 30 caractères et ne doivent pas commencer par un nombre (0-9) ni par un soulignement (_).

Index partiels dans les classes de base abstraites

Un index doit toujours être nommé de façon unique. Cela signifie qu’il n’est pas possible de définir un index partiel dans une classe de base abstraite, dans la mesure où l’option Meta.indexes est héritée par les sous-classes avec exactement les mêmes valeurs d’attributs (y compris name). Pour éviter des collisions de nom, le nom peut contenir '%(app_label)s'``et ``'%(class)s' qui seront remplacés respectivement par l’étiquette de l’application et le nom de la classe du modèle concret (tout en minuscules). Par exemple, Index(fields=['title'], name='%(app_label)s_%(class)s_title_index').

db_tablespace

Index.db_tablespace

Le nom de l”espace de tables de base de données à utiliser pour cet index. Pour les index sur un seul champ et si db_tablespace n’est pas indiqué, l’index est créé dans l’espace db_tablespace du champ.

Si Field.db_tablespace n’est pas présent (ou si l’index utilise plusieurs champs), l’index est créé dans l’espace de tables défini dans l’option db_tablespace dans la classe Meta du modèle. Si aucun de ces espaces n’est défini, l’index est créé dans le même espace de tables que la table.

Voir aussi

Pour une liste des index spécifiques à PostgreSQL, voir django.contrib.postgres.indexes.

opclasses

Index.opclasses

Les noms des classes d’opérateurs PostgreSQL à utiliser pour cet index. Si vous nécessitez une classe d’opérateur personnalisée, vous devez en fournir une pour chaque champ de l’index.

Par exemple, GinIndex(name='json_index', fields=['jsonfield'], opclasses=['jsonb_path_ops']) crée un index gin pour le champ jsonfield en utilisant les classes d’opérateurs jsonb_path_ops.

opclasses est ignoré pour les bases de données autres que PostgreSQL.

Index.name est obligatoire quand on utilise opclasses.

condition

Index.condition

Si la table est très grande et que vos requêtes ciblent principalement un certain sous-ensemble de lignes, il peut être utile de restreindre l’index à ce sous-ensemble. Indiquez une condition sous forme de Q. Par exemple, condition=Q(pages__gt=400) va indexer les lignes dont le champ pages est plus grand que 400.

Index.name est obligatoire quand on utilise condition.

Restrictions pour PostgreSQL

PostgreSQL exige que les fonctions référencées dans la condition soient marquées comme IMMUTABLE. Django ne le vérifie pas, mais PostgreSQL produira une erreur. Cela signifie que des fonctions telles que Fonctions de date et Concat ne sont pas admises. Si vous stockez des dates dans un champ DateTimeField, la comparaison avec des objets datetime peut nécessiter la présence du paramètre tzinfo car sinon la comparaison pourrait aboutir à une fonction « mutable » en raison du forçage de type que Django effectue pour les expressions de requête.

Restrictions pour SQLite

SQLite impose des restrictions sur la façon dont un index partiel peut être construit.

Oracle

Oracle does not support partial indexes. Instead, partial indexes can be emulated by using functional indexes together with Case expressions.

MySQL et MariaDB

Le paramètre condition est ignoré avec MySQL et MariaDB, car aucune de ces bases de données ne prend en charge les index conditionnels.

include

Index.include
New in Django 3.2.

A list or tuple of the names of the fields to be included in the covering index as non-key columns. This allows index-only scans to be used for queries that select only included fields (include) and filter only by indexed fields (fields).

Par exemple :

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

will allow filtering on headline, also selecting pub_date, while fetching data only from the index.

Using include will produce a smaller index than using a multiple column index but with the drawback that non-key columns can not be used for sorting or filtering.

include is ignored for databases besides PostgreSQL.

Index.name is required when using include.

See the PostgreSQL documentation for more details about covering indexes.

Restrictions pour PostgreSQL

PostgreSQL 11+ only supports covering B-Tree indexes, and PostgreSQL 12+ also supports covering GiST indexes.

Back to Top