Skip to content

Commit 41b4343

Browse files
authored
Update DataModels-Databases.md
1 parent 1e872af commit 41b4343

File tree

1 file changed

+148
-5
lines changed

1 file changed

+148
-5
lines changed

DataModels-Databases.md

Lines changed: 148 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- [Паттерны баз данных](#паттерны-баз-данных)
66
- [Движки баз данных](#движки-баз-данных)
77
- [Проблема n + 1](#проблема-n-1)
8+
- [Оптимизация SQL-запросов](#оптимизация-sql-запросов)
89

910
<!--
1011
- [Резидентные базы данных](#резидентные-базы-данных)
@@ -144,22 +145,100 @@ START TRANSACTION;
144145
## Индекс базы данных
145146
- [Об индексе базы данных](#об-индексе-базы-данных)
146147
- [Проблема дублирования данных](#проблема-дублирования-данных)
148+
- [Основные типы индексов](#основные-типы-индексов)
147149

148150
### Об индексе базы данных
149151

150152
**Индекс базы данных** (англ. `database index`) — это структура данных, ускоряющая операции поиска (англ. `speed up querying`) в заданной таблице (или коллекции) базы данных за счёт хранения дополнительной информации в базе (говоря простыми словами, тех же данных таблицы, но в другом виде, в упорядоченном).
151153

152-
По умолчанию записи в таблице (коллекции) могут храниться произвольно (неупорядоченно). И если таблица довольно большая, то последовательный просмотр всех записей может занимать довольно продолжительное время. Индексы приводят данные в такой вид (упорядочивают их), чтобы это ускорило поиск. Например, структура индекста может быть представлена *сбалансированным деревом поиска*, и тогда скорость поиска будет логарифмичной `O(log n)` вместо линейной `O(n)`.
154+
*Индекс* — это дополнительная структура данных, например, в виде дерева, которая позволяет быстро найти нужные строки, не перебирая всю таблицу (англ. `Full Table Scan`). Индексы хранят упорядоченные или быстро доступные ссылки на строки таблицы. Это похоже на оглавление в книге, которое позволяет быстро найти нужную страницу.
155+
156+
157+
По умолчанию записи в таблице (коллекции) могут храниться произвольно (неупорядоченно). И если таблица довольно большая, то последовательный просмотр всех записей может занимать довольно продолжительное время. Индексы приводят данные в такой вид (упорядочивают их), чтобы это ускорило поиск. Например, структура индекса может быть представлена *сбалансированным деревом поиска*, и тогда скорость поиска будет логарифмичной `O(log n)` вместо линейной `O(n)`.
153158

154159
Индекс формируется из значений одного или нескольких столбцов таблицы (полей документов коллекции) и указателя на соответствующие строки таблицы (документы коллекции). Также иногда индексы могут создаваться из выражений.
155160

156-
Таким образом, если вы создаёте индекс по какому-то столбцу таблицы, скажем, по имени пользователя, вы можете быстрее найти (получить) данные пользователей из таблицы по заданному имени (выигрываете в скорости, во времени), но нужно учитывать, что индекс подразумевает дублирование некоторых данных (проигрываете в памяти).
161+
### Основные типы индексов:
162+
#### Бинарное дерево (B-дерево, B-tree)
163+
164+
Наиболее распространённый тип индекса (чаще всего используется по умолчанию). Организован в виде сбалансированного дерева (англ. `AVL-Tree`).
165+
Когда использовать:
166+
• Поиск точных значений (например, `WHERE id = 10`)
167+
• Поиск диапазонов (`WHERE date BETWEEN x AND y`)
168+
• Сортировка (`ORDER BY`)
169+
`JOIN` по индексированным полям
170+
Недостатки:
171+
• Менее эффективен при поиске текста по шаблону (например, с `LIKE '%search%'`)
172+
• Ненужное создание множества таких индексов может снизить производительность при вставке и обновлении записей
173+
174+
#### Хеш-индексы (Hash Index)
175+
Используют хеш-функции для быстрого поиска по точному соответствию ключа.
176+
177+
Когда использовать:
178+
• Очень быстрый поиск по точному совпадению (например, `WHERE username = 'user123'`)
179+
Недостатки:
180+
• Не поддерживают поиск по диапазону (`BETWEEN`, `<`, `>`) или сортировку
181+
• Не подходят для поиска частичных совпадений
182+
• Чаще используются в специализированных БД (например, in-memory хранилищах)
183+
184+
#### Полнотекстовый индекс (Full-Text Index)
185+
186+
Используются для поиска слов или фраз в тексте.
187+
Когда использовать:
188+
• Полнотекстовый поиск по большим текстовым полям (`LIKE` недостаточно эффективен)
189+
Примеры СУБД:
190+
• MySQL (MATCH AGAINST)
191+
• PostgreSQL (GIN, GIN индексы)
192+
193+
#### Многоколоночные (композитные) индексы (Composite Index)
194+
195+
Состоят из нескольких полей таблицы.
196+
197+
Когда использовать:
198+
• Запросы, включающие несколько полей одновременно (WHERE name = X AND date = Y)
199+
• Частые сложные условия с множеством критериев
200+
Важно:
201+
• Порядок столбцов в индексе очень важен. Первым указывается поле, по которому чаще всего происходит поиск или фильтрация.
202+
203+
#### Уникальный индекс (Unique Index)
204+
Не допускает повторяющихся значений.
157205

158-
### Проблема дублирования данных
206+
Когда использовать:
207+
• Поля, значения которых должны быть уникальными (например, `email`, `phone`, `username`)
159208

160-
Важно быть аккуратными с индексами, потому что за любым изменением в таблице (коллекции) должно последовать обновление индекса. Когда данных очень много, это может повлечь за собой очень трудоёмкие вычисления и большую нагрузку на сервер соответственно.
209+
#### Частичные индексы (Partial Index)
161210

162-
Более того, индексы занимают дополнительное место, поэтому не стоит их создавать (хранить) без необходимости.
211+
Индексы, применяемые только к части строк таблицы (по условию).
212+
Когда использовать:
213+
• Если часто выбирается лишь небольшая часть данных (например, только активные пользователи)
214+
215+
#### Многомерные индексы (R-Tree, GIN, GiST)
216+
217+
Используются для специфических типов данных (пространственные данные, JSON и пр.).
218+
Когда использовать:
219+
• Геоданные (например, геолокации, поиск по карте)
220+
• JSON-данные с поиском по внутренним полям
221+
222+
### Преимущества и недостатки индексов
223+
224+
Количество индексов прямо влияет на производительность
225+
* Много индексов:
226+
➕ Ускоряет многие запросы на чтение
227+
➖ Значительно замедляет операции записи (`INSERT, UPDATE, DELETE`), увеличивает размер базы данных, повышает нагрузку на сервер.
228+
* Недостаточно индексов:
229+
➕ Быстрая запись данных
230+
➖ Медленные запросы на чтение, полное сканирование таблиц, неоптимальная нагрузка на сервер.
231+
232+
Таблица с 5 индексами при добавлении новой строки база данных должна обновить все 5 индексов, что занимает больше времени, чем без индексов или с одним индексом.
233+
234+
Создавайте индексы только на те поля, которые часто используются в запросах.
235+
Избегайте индексов на полях с низкой селективностью (например, пол (мужчина/женщина) — плохой кандидат для индекса, так как пользы почти не принесёт).
236+
237+
Правильное использование индексов — это баланс между скоростью чтения, скоростью вставки и обновления данных, а также объёмом используемого места.
238+
239+
Индексы ускоряют чтение, но замедляют операции записи (INSERT, UPDATE, DELETE).
240+
• Используйте индексы осознанно: больше индексов ≠ всегда лучше.
241+
• Регулярно проверяйте производительность запросов (с помощью EXPLAIN) и оптимизируйте набор индексов.
163242

164243
## Курсор
165244
- [О курсоре](#о-курсоре)
@@ -1865,3 +1944,67 @@ GET /posts/_search
18651944
}
18661945
```
18671946
## Mongoose, проблема n + 1 и populate
1947+
1948+
1949+
# Оптимизация SQL-запросов
1950+
1951+
## Анализ производительности запросов
1952+
1953+
Команда `EXPLAIN` — основной инструмент анализа производительности запросов.
1954+
```sql
1955+
EXPLAIN SELECT * FROM users WHERE email = '[email protected]';
1956+
```
1957+
Она позволяет смотреть
1958+
* типы доступа к данным (Index Scan, Full table scan и тд)
1959+
* используемые индексы и их эффективность
1960+
* количество просматриваемых строк
1961+
1962+
## Индексы
1963+
**Индексы***важнейший инструмент ускорения поиска запроса*
1964+
Создавай индекс для полей, которые используются в
1965+
* `JOIN`
1966+
* `WHERE`
1967+
* `ORDER BY`
1968+
* `GROUP BY`
1969+
1970+
Учитывайте **селективность** (индексируй поля с высокой уникальностью).
1971+
1972+
Пример создания индекса
1973+
```sql
1974+
CREATE INDEX idx_users_email ON users(email);
1975+
```
1976+
1977+
## Выбирайте только нужные поля таблицы и не используй `SELECT *`
1978+
```sql
1979+
# плохо
1980+
SELECT *
1981+
# хорошо
1982+
SELECT id, username FROM users; # хорошо
1983+
```
1984+
1985+
## Избегайте лишних JOIN и подзапросов
1986+
Используйте `JOIN` вместо подзапросов, если это возможно
1987+
```sql
1988+
# плохо - подзапрос
1989+
SELECT id, (SELECT id FROM orders WHERE orders.user_id = users.id) FROM users;
1990+
# хорошо - JOIN
1991+
SELECT users.id, orders.id FROM users JOIN orders ON orders.user_id = users.id;
1992+
```
1993+
1994+
## Используйте пагинацию, когда это возможно
1995+
Задайте `LIMIT` и `OFFSET`
1996+
```sql
1997+
SELECT id, username FROM users LIMIT 50 OFFSET 0;
1998+
```
1999+
2000+
## Грамотно используйте условия WHERE и агрегацию
2001+
2002+
## Регулярно чистите базу, выполняйте оптимизацию таблиц и перестройку индексов
2003+
```sql
2004+
OPTIMIZE TABLE your_table
2005+
```
2006+
## Следите за производительностью запросов
2007+
Например, в MySQL можно сделать так
2008+
```sql
2009+
SET GLOBAL slow_query_log = 'ON';
2010+
```

0 commit comments

Comments
 (0)