Добавление условного индекса с конкурентностью

427 0


Бывает приходится добавлять "забытые" индексы когда таблица уже разрослась так, что поиск без индекса становится проблемой.
Хорошо конечно такие ситуации продумывать на этапе проектирования, но практика показывает, что люди ошибаются, а ситуация меняется.
Поэтому вот способ наименее безболезненно добавить индекс в нужную нам модель.

1. В модели поле оставляем как есть и добавляем Meta:

class MyModel(models.Model):
    ...
    field_for_indexed = models.CharField(max_length=100, blank=True, null=True)
    ...

    class Meta:
        indexes = [
            models.Index(
                name='mymodel_by_field_for_indexed',
                fields=['field_for_indexed'],
                # Если требуется условие:
condition=~(Q(field_for_indexed__isnull=True) | Q(field_for_indexed='')),
) ]

2. Запускаем формирование миграций: ./manage.py makemigrations

3. Корректируем миграцию. Меняем AddIndex на AddIndexConcurentry , а также добавляем atomic = False


...
from django.contrib.postgres.operations import AddIndexConcurrently


class Migration(migrations.Migration):
    
    atomic = False
    
    dependencies = [
        ...
    ]
    
    operations = [
        migrations.AlterModelOptions(
            name='mymodel',
            options={},
        ),
        AddIndexConcurrently(
            model_name='mymodel',
            index=models.Index(
                condition=models.Q(
                    ('field_for_indexed__isnull', True), 
                    ('field_for_indexed', ''), 
                    _connector='OR', 
                    _negated=True
                ), 
                fields=['field_for_indexede'], 
                name='maymodel_by_field_for_indexed'
),
), ]
Источник: Creating concurrent indexes

Комментарии

Контактные данные

 Россия, г. Москва