digital-garden/dev/database/Индекс в БД.md

76 lines
11 KiB
Markdown
Raw Normal View History

---
aliases:
- индексов
- индекс
- индексы
- индексирования
- индекса
tags:
- maturity/🌱
date: 2024-10-11
---
**Индекс** — это служебная структура данных, которая позволяет ускорить операции поиска, сортировки и фильтрации данных в реляционных базах данных. Индексы создаются для одного или нескольких столбцов таблицы, с целью [[Оптимизация SQL запросов|ускорения выполнения запросов к базе данных]].
Индексы обычно реализуются на основе различных структур данных, каждая из которых подходит для определённых типов запросов. Наиболее распространённые структуры данных для индексов:
- **B-деревья** ([[../fundamental/structure/B-tree|B-tree]]). Широко применяются для ускорения операций поиска, сортировки и диапазонных запросов.
- **Хэш-индексы.** Хорошо подходят для поиска по точным значениям, но неэффективны для диапазонных запросов.
- **GiST и R-деревья.** Используются для индексации пространственных данных, таких как координаты или географические объекты.
СУБД автоматически выбирает наиболее подходящий индекс для выполнения запроса. Важно следить за тем, чтобы индекс покрывал нужные столбцы и типы запросов, так как ==неправильный выбор индекса может замедлить выполнение запросов.==
**Польза:**
- **Ускорение запросов.** Индексы значительно ускоряют выполнение запросов, особенно для операций равенства, сравнений и сортировки данных.
-ример_: `SELECT * FROM employees WHERE department = 'HR';` — индекс на столбце `department` ускорит выполнение этого запроса.
- **Покрытие запросов.** В некоторых случаях индексы могут содержать все данные, необходимые для выполнения запроса, что позволяет избежать чтения самих строк таблицы (так называемый "[[Покрывающий индекс]]").
-ример_: `SELECT name, age FROM employees WHERE department = 'IT';` — если индекс покрывает столбцы `name`, `age` и `department`, то чтение строк таблицы не потребуется.
- **Поддержка ограничений.** Индексы могут использоваться для реализации ограничений на уникальность данных (UNIQUE), а также для обеспечения ссылочной целостности (FOREIGN KEY).
**Накладные расходы:**
- **Влияние на производительность**: добавление индексов замедляет операции вставки, обновления и удаления, так как индекс должен быть обновлен при каждой модификации данных. При создании индексов необходимо учитывать характер нагрузки на таблицу, особенно если часто выполняются операции записи. Например, при [[Online Transaction Processing|OLTP]] нагрузке чтение данных значительно преобладает над записью (80% чтения и 20% записи), что оправдывает использование индексов.
- **Блокировка таблицы**: добавление индекса блокирует таблицу, что может негативно сказаться на производительности, особенно в [[../../meta/zero/00 HighLoad|высоконагруженных системах]].
- **Дополнительное использование дискового пространства.** Индексы требуют значительного объема дискового пространства для хранения. Обычно объем индексов составляет около половины размера таблицы. Если размер индексов превышает размер таблицы, это может указывать на необходимость оптимизации.
- **Необходимость технического обслуживания.** Со временем индексы могут фрагментироваться и требовать пересоздания для поддержания эффективности. В некоторых системах управления базами данных (СУБД) это может происходить автоматически, однако в других случаях требуется ручное вмешательство.
**Частые ошибки:**
- **Низкая селективность.**: индексы на колонках с низкой [[Селективность колонки|селективностью]] могут оказаться неэффективными и не принести ожидаемого увеличения производительности.
- Индекс на столбце `gender` с двумя возможными значениями (`M`, `F`) не даст значительного выигрыша в производительности.
- **Неиспользуемые индексы**. Индексы, которые не используются, создают дополнительные накладные расходы на хранение и обслуживание. Рекомендуется периодически проверять активность индексов и удалять те, что не используются. Найти такие индексы поможет [[postgresql/pageinspect|pageinspect]].
- **Высокие накладные расходы.** В некоторых случаях затраты на обновление индексов могут превышать выгоды от их использования. Наличие большого количества индексов на одной таблице может вызвать накладные расходы и ухудшить производительность, особенно при частых изменениях данных.
**Когда индексы не работают:**
- **Использование вычисляемых выражений.** Например, выражение `WHERE column + 1 = 10` не будет эффективно использовать индекс. В таких случаях могут применяться специальные методы, такие как индексы по выражению или генерация вычисляемых колонок.
-ример_: Для выражения `column + 1` можно создать вычисляемый столбец и индексировать его.
- **Обработка большого количества записей.** Если запрос возвращает слишком много строк, использование индекса может быть неэффективным.
- **Агрегатные функции.** Лишь некоторые агрегатные функции, такие как `MIN()` и `MAX()`, могут эффективно использовать индексы.
- **Логические операторы.** Индексы хорошо работают с условиями, использующими логический оператор И (`AND`), но менее эффективны с логическим ИЛИ (`OR`):
- **Логические операторы.** Индексы хорошо работают с условиями, использующими логический оператор И (`AND`), но менее эффективны с логическим ИЛИ (`OR`).
-ример запроса с ИЛИ_: `SELECT * FROM tb WHERE a = 0 OR b = 0;` — в этом случае индексы для каждого столбца могут быть использованы независимо (индексы на `a` и `b`), но составной индекс по этим столбцам не будет работать эффективно.
**Какие бывают индексы?**
- **Уникальные и неуникальные.** Уникальные индексы обеспечивают уникальность значений в столбцах. Неуникальные индексы допускают повторяющиеся значения.
- **Простые и составные.** Простые индексы создаются для одного столбца, а [[Составные индексы в БД|составные]] — для нескольких столбцов.
- **Кластерные и некластерные.** Кластерные индексы определяют физическое расположение данных на диске, а некластерные индексы хранят указатели на строки таблицы.
**Реализации:**
- [[postgresql/Индекс в PostgreSQL|Индекс в PostgreSQL]]
- [[../../../../_inbox/Индекс в MySQL|Индекс в MySQL]]
***
## Мета информация
**Область**:: [[../../meta/zero/00 Базы Данных|00 Базы Данных]]
**Родитель**::
**Источник**::
**Создана**:: [[2024-10-11]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
<!-- SerializedQuery: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
- [[Индекс в PostgreSQL]]
- [[Индекс в MySQL]]
- [[Составные индексы в БД]]
- [[Покрывающий индекс]]
<!-- SerializedQuery END -->