Справочник по индексам модели¶
Индексные классы облегчают создание индексов базы данных. Их можно добавить с помощью параметра 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
¶
Позиционный аргумент *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
¶
Список или кортеж имен полей, которые должны быть включены в индекс покрытия в качестве неключевых столбцов. Это позволяет использовать сканирование только индекса для запросов, которые выбирают только включенные поля (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
.