--- aliases: - индексирования tags: - зрелость/🌱 date: - - 2024-03-31 zero-link: - "[[00 PostgreSQL]]" parents: linked: --- Индекс это служебная структура данных, которая позволяет ускорить запросы (поиск, сортировку) к базе данных. **Польза:** - Ускоряют запросы: равенство, сравнения, сортировка - В некоторых случаях позволяют избежать чтения из таблицы. [Покрывающий индекс](Покрывающий%20индекс.md). - Через них можно делать constraints (UNIQUE, FOREIGN KEY) - Специальные оптимизации? **Накладные расходы:** - Дополнительные объемы дискового пространства для хранения индекса. Размер индекса в половину размера таблицы считается нормальным и оптимальным - Обновляются при модификации данных, на что требуется время и ресурсы. Замедление записи в таблицы (80% к 20%). Так как необходимо будет перестраивать индекс при вставке новых значений. - Усложненное технического обслуживание. Индексы пухнут и переодически их нужно пересоздавать **Когда индексы не нужны?** - Малая [Селективность колонки](Селективность%20колонки.md). - Большие накладные расходы на поддержание индекса. - Когда индекс не используется вовсе. **Когда индексы не работают?** - В условии используется вычисляемое выражение: `WHERE counter + 1 = 46` - Если будет отобрано слишком много записей. - Из агрегирующих функций только `min()` и `max()` получат ускорение. - Индексы хорошо работают с логическим И, и плохо работают с логическим ИЛИ. - `SELECT * FROM tb WHERE a = 0 OR b = 0;` - Можно использовать 2 индекса (а) и (b). Индекс (а, b) работать не будет. **Какие бывают индексы?** - Не уникальные и уникальные. Уникальные без повторяющихся значений. - Простые и [составные](Составные%20индексы%20в%20PostgreSQL.md). - Кластерные и некластерные. Кластерные также хранят сами данные рядом с собой. **Типы индексов** - btree - Основан на работе [B-tree](B-tree.md) дерева - Наиболее распространенный тип индексов - Очень хороший алгоритм работы - Покрывает 90% задач - Легко создать ориентируясь на статистику по таблице - Обслуживает как операции сравнения так и операции равенства - Позволяет выполнить сортировку - hash индекс - Абсолютно бесполезен. Используйте btree. - Занимает меньше места на диске, чем btree. - Обслуживает только операции равенства. - Нельзя выполнить сортировку. - gist индекс - В чистом виде полезен для гео-данных. Например, поиск ближайшей гео-точки. - Расширения - pg_trgm - like, ilike, ~, ~* (regexp) - btree_gits - слодные constrains с интервалами. Позволяет переложить на базу данных задачу по контролю пересечения времени. Например, если нужно создать расписание, и чтобы временные интервалы заданий не пересекались. - sp_gist индекс - Нет практических применений в [OLTP](OLTP.md) - Возможно полезен в научной сфере - gin индекс. Нужен тип данных tsvector - Может сильно ухудшить время вставки в таблицу - Хорошо для текстового поиска - Позволяет ускорить поиск по jsonb - jsonb_ops - используется по умолчанию. Индексирует все значения jsonb, из-за этого индекс получается больших размеров. - json_path_ops - заточен на поиск путей в json. То есть позволяет ответить, есть ли такое-то поле в jsonb или его нет. - brin - Компактный индекс - Подходит для упорядоченных данных ## Создание индекса **Что нужно для создания индекса?** - Ориентироваться только на продуктовое окружение, так как тестовые окружения не соответствуют реальности. - Собрать статистику нагрузки на БД от запросов. - Представление [pg_stats](Таблица%20статистик%20pg_stats.md). - Инструменты для сбора статистики: - [pg_stat_statements](pg_stat_statements.md) - отличный инструмент - pgBadger - использовать с осторожностью. Собирает статистику из логов postgres. Но в логи попадают не все запросы. - Иметь примеры запросов с параметрами. - Для понимания входящих параметров запроса. - Необходимо для проверки оптимизаций - Вручную собрать более полную статистику. Редко делается, при необходимости. - По умолчанию PostgrteSQL использует для сбора статистики только 30k строк из таблицы. Из-за этого статистика может расходиться с реальностью. - Уметь читать статистику распределения данных (планировщик). [explain](Профилирование%20запросов%20в%20PostgreSQL.md) При создании индекса важно учитывать [селективность колонки](Селективность%20колонки.md) (разнообразие значений), чем она выше, тем лучше индекс будет выполнять свою задачу. ![](Составные%20индексы%20в%20БД.md#^630c7e) - [PostgreSQL: Documentation: 16: CREATE INDEX](https://www.postgresql.org/docs/current/sql-createindex.html) При добавлении индекса происходит блокировка таблицы. ### Частичный индекс Можно создать частичный индекс по условию, который будет покрывать только записи, которые удовлетворяют определенному условию where. ```sql create index fk_not_null on pgconf(fk_id) where fk id is not null; ``` Допустим, исключим из индекса по FK null значения. В этом случае мы не ускорим работу индекса, так как БД достаточно умная, чтобы делать это автоматически. Но это позволит уменьшить размер индекса. Но на больших данных это также может сказать и на производительности. ## Заметки - Для первичного ключа индекс создается автоматически - Можно отключить автоматическое обновление индекса и сделать обновление ручным ## Полезные команды Расширение pageinspect позволяет изучить структуру индекса (размер страницы, количество страниц и так далее). ```sql create extension pageinspect ``` Посмотреть сколько раз индекс использовался и когда был последний вызов. ```sql select * from pg_stat_user_indexes ``` Посмотреть размер индекса ```sql select pg_size_pretty(pg_indexes_size('orders')) ``` Проверить какие индексы существуют для таблицы: ```sql select * from pg_indexes where tablename='table_name'; ``` Можно получить мета информацию о дереве индекса: ```sql select * from bt_metap('users_pkey'); ``` Можно получить мета информацию о конкретном узле: ```sql select * from bt_page_stats('users_pkey', 3); ``` ## Дополнительные материалы Дополнительные заметки - [Доклад. Индексы в PostgreSQL. Как понять, что создавать](Доклад.%20Индексы%20в%20PostgreSQL.%20Как%20понять,%20что%20создавать.md) Материалы: - [009. B-деревья. Система непересекающихся множеств - М. А. Бабенко - YouTube](https://www.youtube.com/watch?v=KFcpDTpoixo) - [Индексы в PostgreSQL — 1 / Хабр](https://habr.com/ru/companies/postgrespro/articles/326096/) - [Introduction of B+ Tree - GeeksforGeeks](https://www.geeksforgeeks.org/introduction-of-b-tree/)