Справочник по индексам моделей
Классы индексов облегчают создание индексов в базе данных. Их можно добавить, используя опцию Meta.indexes. Этот документ описывает API-справочник класса Index, который включает опции индексов options.
Обращение к встроенным индексам
Индексы определены в django.db.models.indexes, но для удобства они импортированы в django.db.models. Стандартная конвенция заключается в использовании from django.db import models и ссылке на индексы как models.<IndexClass>.
Index options
-
class Index(*expressions, fields=(), name=None, db_tablespace=None, opclasses=(), condition=None, include=None) -
Создаёт индекс (B-дерево) в базе данных.
expressions
-
Index.expressions
Позиционный аргумент *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 operator classes для использования в этом индексе. Если вам требуется пользовательский класс оператора, вы должны предоставить его для каждого поля в индексе.
Например, GinIndex(name='json_index', fields=['jsonfield'],
opclasses=['jsonb_path_ops']) создаёт gin индекс на 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
Список или кортеж имён полей, которые должны быть включены в покрывающий индекс в качестве неключевых столбцов. Это позволяет использовать сканирование только по индексу для запросов, выбирающих только включенные поля (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.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/3.2/ref/models/indexes/