=====================Model index reference=====================.. module:: django.db.models.indexes.. currentmodule:: django.db.modelsIndex classes ease creating database indexes. They can be added using the:attr:`Meta.indexes <django.db.models.Options.indexes>` option. This documentexplains the API references of :class:`Index` which includes the `indexoptions`_... admonition:: Referencing built-in indexesIndexes are defined in ``django.db.models.indexes``, but for conveniencethey're imported into :mod:`django.db.models`. The standard convention isto use ``from django.db import models`` and refer to the indexes as``models.<IndexClass>``.``Index`` options=================.. class:: Index(*expressions, fields=(), name=None, db_tablespace=None, opclasses=(), condition=None, include=None)Creates an index (B-Tree) in the database.``expressions``---------------.. attribute:: Index.expressionsPositional argument ``*expressions`` allows creating functional indexes onexpressions and database functions.For example::Index(Lower('title').desc(), 'pub_date', name='lower_title_date_idx')creates an index on the lowercased value of the ``title`` field in descendingorder 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.:attr:`Index.name` is required when using ``*expressions``... admonition:: Restrictions on OracleOracle requires functions referenced in an index to be marked as``DETERMINISTIC``. Django doesn't validate this but Oracle will error. Thismeans that functions such as:class:`Random() <django.db.models.functions.Random>` aren't accepted... admonition:: Restrictions on PostgreSQLPostgreSQL requires functions and operators referenced in an index to bemarked as ``IMMUTABLE``. Django doesn't validate this but PostgreSQL willerror. This means that functions such as:class:`Concat() <django.db.models.functions.Concat>` aren't accepted... admonition:: MySQL and MariaDBFunctional indexes are ignored with MySQL < 8.0.13 and MariaDB as neithersupports them.``fields``----------.. attribute:: Index.fieldsA list or tuple of the name of the fields on which the index is desired.By default, indexes are created with an ascending order for each column. Todefine an index with a descending order for a column, add a hyphen before thefield's name.For example ``Index(fields=['headline', '-pub_date'])`` would create SQL with``(headline, pub_date DESC)``... admonition:: MySQL and MariaDBIndex ordering isn't supported on MySQL < 8.0.1 and MariaDB < 10.8. In thatcase, a descending index is created as a normal index.``name``--------.. attribute:: Index.nameThe name of the index. If ``name`` isn't provided Django will auto-generate aname. For compatibility with different databases, index names cannot be longerthan 30 characters and shouldn't start with a number (0-9) or underscore (_)... admonition:: Partial indexes in abstract base classesYou must always specify a unique name for an index. As such, youcannot normally specify a partial index on an abstract base class, sincethe :attr:`Meta.indexes <django.db.models.Options.indexes>` option isinherited by subclasses, with exactly the same values for the attributes(including ``name``) each time. To work around name collisions, part of thename may contain ``'%(app_label)s'`` and ``'%(class)s'``, which arereplaced, respectively, by the lowercased app label and class name of theconcrete model. For example ``Index(fields=['title'],name='%(app_label)s_%(class)s_title_index')``.``db_tablespace``-----------------.. attribute:: Index.db_tablespaceThe name of the :doc:`database tablespace </topics/db/tablespaces>` to use forthis index. For single field indexes, if ``db_tablespace`` isn't provided, theindex is created in the ``db_tablespace`` of the field.If :attr:`.Field.db_tablespace` isn't specified (or if the index uses multiplefields), the index is created in tablespace specified in the:attr:`~django.db.models.Options.db_tablespace` option inside the model's``class Meta``. If neither of those tablespaces are set, the index is createdin the same tablespace as the table... seealso::For a list of PostgreSQL-specific indexes, see:mod:`django.contrib.postgres.indexes`.``opclasses``-------------.. attribute:: Index.opclassesThe names of the `PostgreSQL operator classes<https://www.postgresql.org/docs/current/indexes-opclass.html>`_ to use forthis index. If you require a custom operator class, you must provide one foreach field in the index.For example, ``GinIndex(name='json_index', fields=['jsonfield'],opclasses=['jsonb_path_ops'])`` creates a gin index on ``jsonfield`` using``jsonb_path_ops``.``opclasses`` are ignored for databases besides PostgreSQL.:attr:`Index.name` is required when using ``opclasses``.``condition``-------------.. attribute:: Index.conditionIf the table is very large and your queries mostly target a subset of rows,it may be useful to restrict an index to that subset. Specify a condition as a:class:`~django.db.models.Q`. For example, ``condition=Q(pages__gt=400)``indexes records with more than 400 pages.:attr:`Index.name` is required when using ``condition``... admonition:: Restrictions on PostgreSQLPostgreSQL requires functions referenced in the condition to be marked asIMMUTABLE. Django doesn't validate this but PostgreSQL will error. Thismeans that functions such as :ref:`date-functions` and:class:`~django.db.models.functions.Concat` aren't accepted. If you storedates in :class:`~django.db.models.DateTimeField`, comparison to:class:`~datetime.datetime` objects may require the ``tzinfo`` argumentto be provided because otherwise the comparison could result in a mutablefunction due to the casting Django does for :ref:`lookups <field-lookups>`... admonition:: Restrictions on SQLiteSQLite `imposes restrictions <https://www.sqlite.org/partialindex.html>`_on how a partial index can be constructed... admonition:: OracleOracle does not support partial indexes. Instead, partial indexes can beemulated by using functional indexes together with:class:`~django.db.models.expressions.Case` expressions... admonition:: MySQL and MariaDBThe ``condition`` argument is ignored with MySQL and MariaDB as neithersupports conditional indexes.``include``-----------.. attribute:: Index.includeA list or tuple of the names of the fields to be included in the covering indexas non-key columns. This allows index-only scans to be used for queries thatselect only included fields (:attr:`~Index.include`) and filter only by indexedfields (:attr:`~Index.fields`).For example::Index(name='covering_index', fields=['headline'], include=['pub_date'])will allow filtering on ``headline``, also selecting ``pub_date``, whilefetching data only from the index.Using ``include`` will produce a smaller index than using a multiple columnindex but with the drawback that non-key columns can not be used for sorting orfiltering.``include`` is ignored for databases besides PostgreSQL.:attr:`Index.name` is required when using ``include``.See the PostgreSQL documentation for more details about `covering indexes`_... admonition:: Restrictions on PostgreSQLPostgreSQL < 12 only supports covering B-Tree indexes, PostgreSQL 12+ alsosupports covering :class:`GiST indexes<django.contrib.postgres.indexes.GistIndex>`, and PostgreSQL 14+ alsosupports covering :class:`SP-GiST indexes<django.contrib.postgres.indexes.SpGistIndex>`... versionchanged:: 4.1Support for covering SP-GiST indexes with PostgreSQL 14+ was added... _covering indexes: https://www.postgresql.org/docs/current/indexes-index-only-scans.html