ЛЕКЦІЯ 20

Індекси та оптимізація

Основи баз даних

VTFK • 2025

Що вже вивчили

Лекція 19: MongoDB Aggregation

  • Aggregation pipeline етапи
  • $match, $group, $sort
  • JOIN у MongoDB

План лекції

  • Як працюють індекси
  • B-tree структура
  • Коли індексувати
  • EXPLAIN ANALYZE

Фокус: продуктивність запитів

Індекс

Index

Окрема структура даних, яка зберігає відсортовані значення поля з посиланням на рядки.

Аналогія: Як алфавітний покажчик у кінці книги — швидко знайти потрібне

Без індексу: full table scan

B-tree індекс

Структура під капотом

%%{init: {"theme": "neutral", "mermaid": {"version": "11.12.2"}}}%% graph TD Root["Root
(a-m)"] --> L1["Left
(a-d)"] Root --> L2["Middle
(e-l)"] Root --> L3["Right
(m-z)"] L1 --> Data1["Rows:
aa, ab, ad"] L2 --> Data2["Rows:
ee, kg, ll"] L3 --> Data3["Rows:
mm, qw, zz"] style Root fill:#FFE5E5 style L1 fill:#FFE5E5 style L2 fill:#FFE5E5 style L3 fill:#FFE5E5

З індексом: быстрий пошук

Порівняння: scan vs index

Операція Full Scan З індексом Прискорення
10K рядків 10,000 ~14 714x
100K рядків 100,000 ~17 5,882x
1M рядків 1,000,000 ~20 50,000x
10M рядків 10,000,000 ~24 416,666x

Створення індексів (SQL)

Базові синтаксиси

-- Простий індекс
CREATE INDEX idx_email ON users(email);

-- Композитний (на кількох полях)
CREATE INDEX idx_user_created ON orders(user_id, created_at);

-- Унікальний
CREATE UNIQUE INDEX idx_email_unique ON users(email);

-- DESC індекс (для сортування)
CREATE INDEX idx_recent_orders ON orders(created_at DESC);

-- Видалення
DROP INDEX idx_email ON users;

Коли індексувати

EXPLAIN ANALYZE

Перегляд плану виконання

-- Без індексу
EXPLAIN ANALYZE
SELECT * FROM users WHERE email='test@example.com';
-- Seq Scan on users (cost=0.00..35.50, rows=1)

-- З індексом
CREATE INDEX idx_email ON users(email);
EXPLAIN ANALYZE
SELECT * FROM users WHERE email='test@example.com';
-- Index Scan using idx_email (cost=0.29..8.30, rows=1)

査план выполнення

Порівняння стратегій

%%{init: {"theme": "neutral", "mermaid": {"version": "11.12.2"}}}%% flowchart LR Query[SELECT WHERE] --> Choose{Індекс
існує?} Choose -->|Немає| Seq[Sequential Scan
O(n)] Choose -->|Так| Idx[Index Lookup
O(log n)] Seq --> Result1["Повільно:
1M шукань"] Idx --> Result2["Швидко:
20 шукань"] style Result1 fill:#FFE5E5 style Result2 fill:#E5FFE5

Типи індексів

Композитний індекс

Оптимізація сложних запитів

-- Поширений запит
SELECT * FROM orders 
WHERE user_id=123 AND created_at>'2025-01-01'
ORDER BY created_at DESC
LIMIT 10;

-- Оптимальний індекс
CREATE INDEX idx_user_created ON orders(
  user_id,      -- перше (більш селективне)
  created_at DESC -- друге (для ORDER BY)
);

-- Тепер БД використовує один індекс

Міні-вікторина

На скільки полів потрібен індекс для запиту: WHERE a=1 AND b=2 AND c=3?

  • Потрібно 3 індекси
  • Можна 1 композитний
  • Індекси не потрібні
✅ Правильна відповідь: Можна 1 композитний
💡 Пояснення:

Композитний індекс (a, b, c) покриває всі три умови за один lookup

Помилка: забагато індексів

⚠️ ЗАСТЕРЕЖЕННЯ

Індекси сповільнюють INSERT/UPDATE/DELETE

❌ Неправильно

-- 20+ індексів на таблиці
CREATE INDEX idx1 ON products(name);
CREATE INDEX idx2 ON products(price);
CREATE INDEX idx3 ON products(category);
-- Більше індексів = більше запису

БД оновлює всі індекси при INSERT

✓ Правильно

-- 3-5 індексів на поширені запити
CREATE INDEX idx_name_price ON products(name, price);
CREATE INDEX idx_category ON products(category);
-- Меньше = швидше

Індексуй тільки критичне

Стратегія індексування

Partial & Filtered індекси

Пример: e-commerce оптимізація

Реальний сценарій

-- Товари
CREATE INDEX idx_active_category ON products(
  category, price DESC
) WHERE active=true;

-- Замовлення
CREATE INDEX idx_user_recent ON orders(
  user_id, created_at DESC
);

-- Пошук
CREATE INDEX idx_product_search ON products(
  name COLLATE utf8_general_ci
) USING FULLTEXT;

Підсумки

  • Індекси за логарифмічний час O(log n)
  • Композитні індекси для складних запитів
  • EXPLAIN ANALYZE показує реальний план

Вимірюй перед оптимізацією!

Домашнє завдання

Наступна лекція:

Лекція 21: Підсумки

📚 Корисні ресурси:

📚 Корисні ресурси:

Дякую за увагу! 💾

← Повернутися до списку лекцій