Справочник системных ошибок и решений

Windows Server, Active Directory, 1С:Предприятие, СУБД, Linux, Cisco, MikroTik, Asterisk.

⚠️ Важная информация Все материалы, инструкции, команды и скрипты на сайте предоставлены исключительно в ознакомительных целях. Их применение может повлиять на работу операционной системы, программного обеспечения, баз данных, сетевого оборудования и других компонентов инфраструктуры. Перед выполнением действий создайте резервную копию и по возможности протестируйте изменения в безопасной среде. Пользователь самостоятельно оценивает риски и несет ответственность за результат. При отсутствии необходимых знаний обратитесь к квалифицированному ИТ-специалисту.

INEFFICIENT_INDEX_STRATEGY 1С:Предприятие и СУБД

Типы индексов PostgreSQL: B-Tree, GIN, GiST, BRIN — Руководство по выбору

Обновлено: 26.08.2026 · Официальная документация ↗
  • Чрезмерный размер индексов на диске, превышающий объем самих данных таблицы.
  • Медленный полнотекстовый поиск или поиск внутри полей JSONB и массивов.
  • Критическое падение скорости выполнения операций INSERT/UPDATE из-за оверхеда на поддержку индексов.

1. B-Tree (Стандарт для точных совпадений и диапазонов)

Применяется по умолчанию для операций =, <, >, BETWEEN, ORDER BY:

CREATE INDEX idx_users_email ON users USING btree(email);

-- Индекс с покрывающими колонками (Covering Index) для Index Only Scan
CREATE INDEX idx_orders_covering ON orders (customer_id) INCLUDE (order_date, total_amount);

2. GIN (Generalized Inverted Index — JSONB, массивы, Full-Text)

Оптимален для поиска элементов внутри коллекций и текстового поиска (?, @>, @@):

-- Индексация JSONB атрибутов
CREATE INDEX idx_products_attributes ON products USING gin(attributes jsonb_path_ops);

-- Полнотекстовый поиск с генерацией tsvector
CREATE INDEX idx_articles_fts ON articles USING gin(to_tsvector('russian', content));

3. GiST (Generalized Search Tree — Геометрия, диапазоны, схожесть)

Используется для PostGIS, перекрывающихся интервалов (`&&`) и триграммного поиска подстрок (`LIKE '%substr%'`):

CREATE EXTENSION IF NOT EXISTS pg_trgm;
CREATE EXTENSION IF NOT EXISTS btree_gist;

-- Быстрый ILIKE поиск по подстроке
CREATE INDEX idx_clients_name_trgm ON clients USING gist(full_name gist_trgm_ops);

-- Запрет пересечения интервалов времени (Exclusion Constraint)
ALTER TABLE room_booking ADD CONSTRAINT no_overlap 
EXCLUDE USING gist (room_id WITH =, booking_period WITH &&);

4. BRIN (Block Range Index — Огромные хронологические таблицы)

Хранит минимум/максимум значений для пачки блоков (pages). Занимает в сотни раз меньше места:

CREATE INDEX idx_logs_created_at_brin ON system_logs USING brin(created_at) WITH (pages_per_range = 64);
💡 Практика специалистов: Для логов, метрик и аудита размером в сотни гигабайт всегда тестируйте BRIN индексы вместо B-Tree. Вы сэкономите до 98% оперативной памяти и дискового пространства.

Частые вопросы (FAQ)

В чем разница между jsonb_ops и jsonb_path_ops для GIN индексов?

jsonb_ops индексирует каждый ключ и каждое значение отдельно, поддерживая любые операторы (? , ?&, @>). jsonb_path_ops хэширует полные пути 'ключ-значение', индекс получается намного компактнее и быстрее, но поддерживает только оператор @>.

Когда BRIN индекс не будет работать эффективно?

BRIN эффективен только тогда, когда физическое расположение строк на диске коррелирует со значениями столбца (например, автоинкрементные ID или даты добавления). Если данные перемешаны, BRIN будет сканировать почти все блоки.

Как построить индекс на большой production-таблице без блокировки записи?

Используйте параметр CONCURRENTLY: CREATE INDEX CONCURRENTLY idx_name ON table(col);. Это предотвращает эксклюзивную блокировку ShareLock на запись.

Что такое partial index (частичный индекс) и зачем он нужен?

Частичный индекс строится с условием WHERE (например, CREATE INDEX ON orders(status) WHERE status = 'active';). Он экономит память, индексируя только нужную для бизнес-логики часть строк.

Полезные материалы
Рекомендуем