123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- =====================
- Model index reference
- =====================
- .. module:: django.db.models.indexes
- .. currentmodule:: django.db.models
- Index classes ease creating database indexes. They can be added using the
- :attr:`Meta.indexes <django.db.models.Options.indexes>` option. This document
- explains the API references of :class:`Index` which includes the `index
- options`_.
- .. admonition:: Referencing built-in indexes
- Indexes are defined in ``django.db.models.indexes``, but for convenience
- they're imported into :mod:`django.db.models`. The standard convention is
- to 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.expressions
- Positional argument ``*expressions`` allows creating functional indexes on
- expressions 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 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.
- :attr:`Index.name` is required when using ``*expressions``.
- .. admonition:: 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
- :class:`Random() <django.db.models.functions.Random>` aren't accepted.
- .. admonition:: Restrictions on 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
- :class:`Concat() <django.db.models.functions.Concat>` aren't accepted.
- .. admonition:: MySQL and MariaDB
- Functional indexes are ignored with MySQL < 8.0.13 and MariaDB as neither
- supports them.
- ``fields``
- ----------
- .. attribute:: Index.fields
- A 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. To
- define an index with a descending order for a column, add a hyphen before the
- field's name.
- For example ``Index(fields=['headline', '-pub_date'])`` would create SQL with
- ``(headline, pub_date DESC)``.
- .. admonition:: MariaDB
- Index ordering isn't supported on MariaDB < 10.8. In that case, a
- descending index is created as a normal index.
- ``name``
- --------
- .. attribute:: Index.name
- The name of the index. If ``name`` isn't provided Django will auto-generate a
- name. For compatibility with different databases, index names cannot be longer
- than 30 characters and shouldn't start with a number (0-9) or underscore (_).
- .. admonition:: Partial indexes in abstract base classes
- You must always specify a unique name for an index. As such, you
- cannot normally specify a partial index on an abstract base class, since
- the :attr:`Meta.indexes <django.db.models.Options.indexes>` option is
- inherited by subclasses, with exactly the same values for the attributes
- (including ``name``) each time. To work around name collisions, part of the
- name may contain ``'%(app_label)s'`` and ``'%(class)s'``, which are
- replaced, respectively, by the lowercased app label and class name of the
- concrete model. For example ``Index(fields=['title'],
- name='%(app_label)s_%(class)s_title_index')``.
- ``db_tablespace``
- -----------------
- .. attribute:: Index.db_tablespace
- The name of the :doc:`database tablespace </topics/db/tablespaces>` to use for
- this index. For single field indexes, if ``db_tablespace`` isn't provided, the
- index is created in the ``db_tablespace`` of the field.
- If :attr:`.Field.db_tablespace` isn't specified (or if the index uses multiple
- fields), 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 created
- in the same tablespace as the table.
- .. seealso::
- For a list of PostgreSQL-specific indexes, see
- :mod:`django.contrib.postgres.indexes`.
- ``opclasses``
- -------------
- .. attribute:: Index.opclasses
- The names of the `PostgreSQL operator classes
- <https://www.postgresql.org/docs/current/indexes-opclass.html>`_ to use for
- this index. If you require a custom operator class, you must provide one for
- each 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.condition
- If 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 PostgreSQL
- PostgreSQL requires functions referenced in the condition to be marked as
- IMMUTABLE. Django doesn't validate this but PostgreSQL will error. This
- means that functions such as :ref:`date-functions` and
- :class:`~django.db.models.functions.Concat` aren't accepted. If you store
- dates in :class:`~django.db.models.DateTimeField`, comparison to
- :class:`~datetime.datetime` objects may require the ``tzinfo`` argument
- to be provided because otherwise the comparison could result in a mutable
- function due to the casting Django does for :ref:`lookups <field-lookups>`.
- .. admonition:: Restrictions on SQLite
- SQLite `imposes restrictions <https://www.sqlite.org/partialindex.html>`_
- on how a partial index can be constructed.
- .. admonition:: Oracle
- Oracle does not support partial indexes. Instead, partial indexes can be
- emulated by using functional indexes together with
- :class:`~django.db.models.expressions.Case` expressions.
- .. admonition:: MySQL and MariaDB
- The ``condition`` argument is ignored with MySQL and MariaDB as neither
- supports conditional indexes.
- ``include``
- -----------
- .. attribute:: Index.include
- 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 (:attr:`~Index.include`) and filter only by indexed
- fields (:attr:`~Index.fields`).
- For example::
- 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.
- :attr:`Index.name` is required when using ``include``.
- See the PostgreSQL documentation for more details about `covering indexes`_.
- .. admonition:: Restrictions on PostgreSQL
- PostgreSQL supports covering B-Tree and :class:`GiST indexes
- <django.contrib.postgres.indexes.GistIndex>`. PostgreSQL 14+ also supports
- covering :class:`SP-GiST indexes
- <django.contrib.postgres.indexes.SpGistIndex>`.
- .. _covering indexes: https://www.postgresql.org/docs/current/indexes-index-only-scans.html
|