← Назад к вопросам

В каких операциях используется индекс

2.3 Middle🔥 151 комментариев
#Базы данных и SQL

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

В каких операциях используется индекс

Индексы в базах данных - это критические структуры для оптимизации производительности. Давайте разберемся, в каких операциях SQL они используются и как это влияет на производительность.

Основные операции с индексами

1. WHERE с условиями поиска

Это главная область использования индексов:

-- БЕЗ индекса: полное сканирование таблицы (O(n))
SELECT * FROM users WHERE id = 42;

-- С индексом на id: быстрый поиск (O(log n))
CREATE INDEX idx_users_id ON users(id);
SELECT * FROM users WHERE id = 42; -- ✓ Использует индекс

-- С индексом на email: быстрый поиск
CREATE INDEX idx_users_email ON users(email);
SELECT * FROM users WHERE email = user@example.com; -- ✓ Использует индекс

2. JOIN операции

Индексы на foreign key очень ускоряют join:

-- Индекс на user_id в orders помогает быстро найти заказы пользователя
CREATE INDEX idx_orders_user_id ON orders(user_id);

-- Эта операция будет быстрой
SELECT u.name, o.amount 
FROM users u
JOIN orders o ON u.id = o.user_id
WHERE u.id = 5; -- ✓ Индексы на оба id ускоряют join

3. ORDER BY и сортировка

Индексы могут избежать явной сортировки:

-- БЕЗ индекса: сортировка в памяти
SELECT * FROM users ORDER BY created_at DESC;

-- С индексом: уже отсортировано
CREATE INDEX idx_users_created_at ON users(created_at DESC);
SELECT * FROM users ORDER BY created_at DESC; -- ✓ Нет Sort операции

-- Индекс на составном ключе помогает при сортировке по нескольким полям
CREATE INDEX idx_users_status_created ON users(status, created_at);
SELECT * FROM users WHERE status = active ORDER BY created_at;

4. DISTINCT операции

-- Индекс помогает найти уникальные значения быстрее
CREATE INDEX idx_users_country ON users(country);

SELECT DISTINCT country FROM users; -- ✓ Быстрее с индексом
SELECT COUNT(DISTINCT country) FROM users; -- ✓ Может быть быстрее

5. GROUP BY агрегация

-- Индекс на поле для группировки ускоряет результат
CREATE INDEX idx_orders_customer_id ON orders(customer_id);

SELECT customer_id, COUNT(*), SUM(amount) 
FROM orders
GROUP BY customer_id; -- ✓ Может использовать индекс

6. LIMIT с OFFSET

-- Без индекса на ORDER BY, LIMIT может быть медленным
SELECT * FROM users ORDER BY id LIMIT 10 OFFSET 1000000;
-- Может отсканировать 1 миллион строк даже при LIMIT 10

-- С индексом на id: быстрый LIMIT
CREATE INDEX idx_users_id ON users(id);
SELECT * FROM users ORDER BY id LIMIT 10 OFFSET 1000000; -- ✓ Быстрее

7. BETWEEN и диапазоны

-- Индекс очень эффективен для диапазонных запросов
CREATE INDEX idx_orders_created_at ON orders(created_at);

-- Все эти запросы используют индекс
SELECT * FROM orders WHERE created_at BETWEEN 2024-01-01 AND 2024-12-31;
SELECT * FROM orders WHERE created_at >= 2024-01-01;
SELECT * FROM orders WHERE price > 100 AND price < 1000;

8. IN и OR условия

-- Индекс помогает при IN
CREATE INDEX idx_users_status ON users(status);

SELECT * FROM users WHERE status IN (active, premium); -- ✓ Использует индекс

-- OR может использовать индексы на оба столбца
CREATE INDEX idx_posts_user_id ON posts(user_id);
CREATE INDEX idx_posts_category_id ON posts(category_id);

SELECT * FROM posts WHERE user_id = 1 OR category_id = 5; -- ✓ Возможно использует оба индекса

Составные индексы (Composite Indexes)

-- Составной индекс может использоваться для нескольких целей
CREATE INDEX idx_users_country_city ON users(country, city);

-- Это использует индекс
SELECT * FROM users WHERE country = US AND city = NY;

-- Это тоже использует индекс
SELECT * FROM users WHERE country = US;

-- Это НЕ использует индекс (пропущен первый столбец)
SELECT * FROM users WHERE city = NY; -- ✗ Не эффективно

Операции, где индексы НЕ помогают

-- LIKE с % в начале (приходится сканировать все)
SELECT * FROM users WHERE email LIKE %@example.com; -- ✗ Нет индекса

-- LIKE с % в конце (индекс может помочь)
SELECT * FROM users WHERE email LIKE user%; -- ✓ Может использовать индекс

-- Функции на столбце (обычно не используют индекс)
SELECT * FROM users WHERE UPPER(email) = USER@EXAMPLE.COM; -- ✗ Нет индекса

-- Арифметические операции
SELECT * FROM products WHERE price * quantity > 1000; -- ✗ Нет индекса
SELECT * FROM products WHERE price > 1000 / quantity; -- ✗ Нет индекса

-- NOT IN (обычно неэффективно)
SELECT * FROM orders WHERE customer_id NOT IN (1, 2, 3); -- ✗ Полное сканирование

В Java коде

// JPA/Hibernate с индексами
@Entity
public class User {
    @Id
    private Long id;
    
    @Column(name = "email", unique = true)
    private String email; // Уникальный индекс автоматически
    
    @Column(name = "created_at")
    @Index(name = "idx_created_at") // Явный индекс
    private LocalDateTime createdAt;
}

// Query быстрая благодаря индексам
public interface UserRepository extends JpaRepository<User, Long> {
    // Использует индекс на id (primary key)
    Optional<User> findById(Long id);
    
    // Использует индекс на email
    Optional<User> findByEmail(String email);
    
    // Использует индекс на created_at и сортировку
    List<User> findAllByOrderByCreatedAtDesc();
}

// Но плохие запросы остаются медленными
public interface UserRepository extends JpaRepository<User, Long> {
    // Без индекса на name - полное сканирование
    List<User> findByName(String name);
    
    // LIKE в начале - полное сканирование
    @Query("SELECT u FROM User u WHERE u.email LIKE %:email")
    List<User> findByEmailLike(@Param("email") String email);
}

Проверка использования индекса

-- PostgreSQL
EXPLAIN ANALYZE
SELECT * FROM users WHERE email = user@example.com;

-- MySQL
EXPLAIN
SELECT * FROM users WHERE email = user@example.com;
-- Смотреть на "key" и "rows" для оценки эффективности

Выводы

Индексы ускоряют:

  • WHERE условия (особенно ==, <, >, BETWEEN)
  • JOIN операции по foreign keys
  • ORDER BY и LIMIT (сортировка)
  • GROUP BY агрегацию
  • DISTINCT

Индексы НЕ помогают:

  • LIKE %value (в начале)
  • Функции на столбцах
  • Арифметика на столбцах
  • NOT IN
  • Полные сканирования для анализа

Лучшая практика - создавать индексы на столбцы, которые часто используются в WHERE, JOIN, ORDER BY и сортировке.