Индексы
Индексные классы облегчают создание индексов базы данных. Их можно добавить с помощью параметра Meta.indexes. Этот документ объясняет API Index, который включает в себя index options.
Встроенные индексы
Индексы определены в django.db.models.indexes, но для удобства они импортированы в django.db.models. Стандартное соглашение - использовать from django.db import models и ссылаться на индексы как на models.<IndexClass>.
Опции Index
class Index(*expressions, fields=(), name=None, db_tablespace=None, opclasses=(), condition=None, include=None)[исходный код]
Создает индекс (B-Tree) в базе данных.
expressions
Index.expressions
New in Django 3.2.
Позиционный аргумент *expressions позволяет создавать функциональные индексы для выражений и функций базы данных.
Например:
Index(Lower('title').desc(), 'pub_date', name='lower_title_date_idx')
создает индекс для значения в нижнем регистре поля title в порядке убывания и поля pub_date в порядке возрастания по умолчанию.
Другой пример:
Index(F('height') * F('weight'), Round('weight'), name='calc_idx')
создает индекс для результата умножения полей height и weight и weight с округлением до ближайшего целого числа.
Index.name требуется при использовании *expressions.
Ограничения для 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']) создаст SQL с (headline, pub_date DESC). Порядок индекса не поддерживается в MySQL. В этом случае нисходящий индекс создается как обычный индекс.
name
Index.name
Название индекса. Если name не указано, Django автоматически сгенерирует имя. Для совместимости с различными базами данных имена индексов не могут быть длиннее 30 символов и не должны начинаться с цифры (0-9) или подчеркивания (_).
Частичные индексы в абстрактных базовых классах
Вы всегда должны указывать уникальное имя для индекса. Таким образом, вы не можете обычно указывать частичный индекс для абстрактного базового класса, так как опция Meta.indexes наследуется подклассами, с точно такими же значениями для атрибуты (включая name) каждый раз. Чтобы обойти коллизии имен, часть имени может содержать '%(app_label)s' и '%(class)s', которые заменяются соответственно меткой приложения в нижнем регистре и именем класса конкретной модели. Например, Index(fields=['title'], name='%(app_label)s_%(class)s_title_index').
db_tablespace
Index.db_tablespace
Имя табличного пространства базы данных для использования в этом индексе. Для индексов с одним полем, если db_tablespace не указан, индекс создается в db_tablespace поля.
Если Field.db_tablespace не указан (или если индекс использует несколько полей), индекс создается в табличном пространстве, указанном в параметре db_tablespace внутри class Meta модели. Если ни одно из этих табличных пространств не задано, индекс создается в том же табличном пространстве, что и таблица.
См.также
Список специфичных для PostgreSQL индексов см. в разделе django.contrib.postgres.indexes.
opclasses
Index.opclasses
Имена классов операторов PostgreSQL для использования в этом индексе. Если вам требуется пользовательский класс операторов, вы должны предоставить его для каждого поля в индексе.
Например, GinIndex(name='json_index', fields=['jsonfield'], opclasses=['jsonb_path_ops']) создает джин индекс для jsonfield, используя jsonb_path_ops.
opclasses игнорируются для всех баз данных, кроме PostgreSQL.
Index.name требуется при использовании opclasses.
condition
Index.condition
Если таблица очень большая и ваши запросы в основном нацелены на подмножество строк, может быть полезно ограничить индекс этим подмножеством. Укажите условие как Q. Например, condition=Q(pages__gt=400) индексирует записи с более чем 400 страницами.
Index.name требуется при использовании condition.
Ограничения для PostgreSQL
PostgreSQL требует, чтобы функции, на которые есть ссылки в условии, были помечены как IMMUTABLE. Django не проверяет это, но PostgreSQL выдаст ошибку. Это означает, что такие функции, как Функции даты и Concat, не принимаются. Если вы храните даты в DateTimeField, сравнение с объектами datetime может потребовать предоставления аргумента tzinfo, так как в противном случае сравнение может привести к изменяемой функции из-за приведения, который Django выполняет для фильтров.
Ограничения для SQLite
SQLite накладывает ограничения на то, как можно построить частичный индекс.
Oracle
Oracle не поддерживает частичные индексы. Вместо этого частичные индексы можно эмулировать, используя функциональные индексы вместе с выражениями Case.
MySQL и MariaDB
Аргумент condition игнорируется MySQL и MariaDB, поскольку ни один из них не поддерживает условные индексы.
include
Index.include
New in Django 3.2.
Список или кортеж имен полей, которые должны быть включены в индекс покрытия в качестве неключевых столбцов. Это позволяет использовать сканирование только индекса для запросов, которые выбирают только включенные поля (include) и фильтруют только по индексированным полям (fields).
Например:
Index(name='covering_index', fields=['headline'], include=['pub_date'])
позволит фильтровать по headline, также выбирая pub_date, при этом данные будут извлекаться только из индекса.
Использование include дает меньший индекс, чем использование индекса с несколькими столбцами, но с недостатком, заключающимся в том, что неключевые столбцы нельзя использовать для сортировки или фильтрации.
include игнорируется для всех баз данных, кроме PostgreSQL.
Index.name требуется при использовании include.
Смотрите документацию PostgreSQL для получения более подробной информации о прикрытии индексов.
Ограничения для PostgreSQL
PostgreSQL 11+ поддерживает только покрывающие индексы B-Tree, а PostgreSQL 12+ также поддерживает покрывающие GiST indexes.