# Documentation Django 5.2.8

# 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

L’argument positionnel `*expressions` permet de créer des index fonctionnels sur des expressions et des fonctions de base de données.

Par exemple :

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

crée un index sur la valeur en minuscules du champ `title` dans l’ordre alphabétique inverse et le champ `pub_date` dans l’ordre alphabétique par défaut.

Un autre exemple :

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

crée un index sur le résultat de la multiplication des champs `height` et `weight` avec le champ `weight` arrondi à l’entier le plus proche.

`Index.name` est obligatoire quand on utilise `*expressions`.

Restrictions avec Oracle

Oracle exige que les fonctions référencées dans un index soient marquées comme `DETERMINISTIC`. Django ne vérifie pas cela mais Oracle produit une erreur si ce n’est pas le cas. Cela signifie que les fonctions telles que `Random()` ne sont pas admises.

Restrictions pour PostgreSQL

PostgreSQL exige que les fonctions et les opérateurs référencés dans un index soient marquées comme `IMMUTABLE`. Django ne vérifie pas cela mais PostgreSQL produit une erreur si ce n’est pas le cas. Cela signifie que les fonctions telles que `Concat()` ne sont pas admises.

MySQL et MariaDB

Les index fonctionnels sont ignorés avec MySQL < 8.0.13 et MariaDB car aucun des deux ne les prend en charge.

### `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'])` créerait du SQL contenant `(headline, pub_date DESC)`.

MariaDB

L’ordonnancement des index n’est pas pris en charge par MariaDB < 10.8. Dans ce cas, un index décroissant est créé 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 ne prend pas en charge les index partiels. Par contre, les index partiels peuvent être émulés à l’aide d’index fonctionnels en lien avec des expressions `Case`.

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

Une liste ou un tuple de noms de champs à inclure dans l’index couvrant, représentant des colonnes qui ne sont pas des clés. Cela permet des analyses en index pur avec des requêtes qui ne sélectionnent que les champs inclus (`include`) et qui ne filtrent que sur les champs indexés (`fields`).

Par exemple :

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

permettra le filtrage sur `headline`, sélectionnant aussi `pub_date`, tout en ne récupérant les données qu’à partir de l’index.

Avec `include`, l’index produit est plus petit qu’en utilisant un index sur plusieurs colonnes mais avec l’inconvénient que les colonnes n’étant pas des clés ne peuvent pas être utilisées pour le tri ou le filtrage.

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

`Index.name` est obligatoire quand on utilise `include`.

Consultez la documentation PostgreSQL pour plus de détails au sujet des index couvrants.

Restrictions pour PostgreSQL

PostgreSQL prend en charge les index couvrants de type B-Tree et `GiST indexes`. PostgreSQL 14+ gère en plus les index couvrants de type `SP-GiST`.