PurpleSchool — курсы программирования онлайн
  • Пути
    • Frontend React разработчик
    • Frontend Vue разработчик
    • Backend разработчик Node.js
    • Fullstack разработчик React / Node.js
    • Mobile разработчик React Native
    • Backend разработчик Golang
    • Devops инженер
    • Backend разработчик Python
  • AI для кодаНовое
  • О нас
    • Отзывы
    • Реферальная программа
    • О компании
    • Контакты
  • Иконка открытия меню
    • Сообщество
    • PurpleПлюс
    • AI Собеседование
    • AI тренажёр
    • Проекты
PurpleSchool — платформа бесплатных roadmap и курсов для разработчиков
ютуб иконка
Telegram иконка
VK иконка
VK иконка
Курсы
ГлавнаяКаталог курсовFrontendBackendFullstack
Практика
КарьераПроектыPurpleПлюс
Материалы
БлогБаза знаний
Документы
Договор офертаПолитика конфиденциальностиПроверка сертификатаМиграция курсовРеферальная программа
Реквизиты
ИП Ларичев Антон АндреевичИНН 773373765379contact@purpleschool.ru

PurpleSchool © 2020 -2026 Все права защищены

  • Курсы
    • FrontendИконка стрелки
    • AI разработкаИконка стрелки
    • BackendИконка стрелки
    • DevOpsИконка стрелки
    • MobileИконка стрелки
    • ТестированиеИконка стрелки
    • Soft-skillsИконка стрелки
    • ДизайнИконка стрелки
    Иконка слояПерейти в каталог курсов
  • Бесплатно
    • Курсы
    • JavaScript Основы разработкиPython Основы PythonCSS CSS FlexboxКарта развитияВопросы для собеседований
    • База знанийИконка стрелки
    • Новостные рассылкиИконка стрелки
  • PurpleSchool — курсы программирования онлайн
    • AI для кодаНовое
    • Сообщество
    • PurpleПлюс
    • AI Собеседование
    • AI тренажёр
    • Проекты
    Главная
    Сообщество
    Индексы в PostgreSQL: типы, применение и подводные камни

    Индексы в PostgreSQL: типы, применение и подводные камни

    Аватар автора Индексы в PostgreSQL: типы, применение и подводные камни

    Антон Ларичев

    Иконка календаря05 июля 2026
    PostgreSQLбазы данныхиндексыоптимизацияпроизводительностьSQLmiddleИконка уровня middle
    Картинка поста Индексы в PostgreSQL: типы, применение и подводные камни

    Введение

    Индексы — один из главных инструментов оптимизации PostgreSQL. Правильный выбор типа индекса ускоряет запросы в десятки раз, неправильный — замедляет запись и занимает лишнее место на диске. PostgreSQL поддерживает несколько типов индексов, каждый из которых оптимизирован под конкретные сценарии. В этой статье разберём их внутреннее устройство и практические правила применения.

    B-Tree индексы

    B-Tree (сбалансированное дерево) — тип по умолчанию. Он покрывает большинство задач: сравнение на равенство, диапазонные запросы, сортировка.

    -- Создание обычного B-Tree индекса
    CREATE INDEX idx_users_email ON users (email);
    
    -- Составной индекс для фильтрации и сортировки одновременно
    CREATE INDEX idx_orders_user_date ON orders (user_id, created_at DESC);
    

    Правила применения:

    • Операции =, <, >, BETWEEN, LIKE 'prefix%'
    • ORDER BY и GROUP BY
    • Составные ключи — колонки с высокой селективностью ставьте первыми

    Hash индексы

    Hash индексы хранят хеш значения ключа и оптимизированы исключительно для проверки на равенство. С PostgreSQL 10 они стали WAL-логируемыми и надёжными.

    -- Hash-индекс оправдан только при запросах с =
    CREATE INDEX idx_sessions_token ON sessions USING HASH (token);
    
    -- Запрос, который выигрывает от hash-индекса
    SELECT * FROM sessions WHERE token = 'abc123xyz';
    

    Правила применения:

    • Только операции равенства (диапазоны не поддерживаются)
    • Поля с высокой кардинальностью: UUID, токены, хеши
    • Когда компактность важнее универсальности

    GiST индексы

    GiST (Generalized Search Tree) — расширяемая структура для сложных типов данных: геометрия, диапазоны, полнотекстовый поиск.

    -- Индекс для геометрических данных
    CREATE INDEX idx_locations_point ON locations USING GIST (coords);
    
    -- Поиск точек в радиусе 10 единиц
    SELECT * FROM locations
    WHERE coords <-> '(55.75, 37.62)'::point < 10;
    
    -- Индекс для диапазонных типов
    CREATE INDEX idx_bookings_period ON bookings USING GIST (period);
    
    -- Поиск пересечений диапазонов дат
    SELECT * FROM bookings
    WHERE period && '[2024-01-01, 2024-01-31]'::daterange;
    

    GIN индексы

    GIN (Generalized Inverted Index) — инвертированный индекс для значений, содержащих множество элементов: массивы, JSONB, полнотекстовый поиск.

    -- Индекс для JSONB-поля с атрибутами товаров
    CREATE INDEX idx_products_attrs ON products USING GIN (attributes);
    
    -- Поиск всех товаров красного цвета через containment-оператор
    SELECT * FROM products WHERE attributes @> '{"color": "red"}';
    
    -- Индекс для полнотекстового поиска на русском языке
    CREATE INDEX idx_articles_fts ON articles
    USING GIN (to_tsvector('russian', body));
    
    -- Полнотекстовый поиск с несколькими ключевыми словами
    SELECT * FROM articles
    WHERE to_tsvector('russian', body) @@ to_tsquery('russian', 'PostgreSQL & индекс');
    

    BRIN индексы

    BRIN (Block Range INdex) — сверхкомпактный индекс для больших таблиц с физической корреляцией между значением поля и расположением строки на диске.

    -- BRIN для таблицы событий с монотонно возрастающей датой
    CREATE INDEX idx_events_created ON events USING BRIN (created_at);
    
    -- Запрос по диапазону — сканируются только нужные блоки диска
    SELECT * FROM events
    WHERE created_at BETWEEN '2024-01-01' AND '2024-03-31';
    

    BRIN в 100–1000 раз меньше B-Tree, но эффективен только при высокой корреляции: timeseries, автоинкрементные ID, данные с последовательной вставкой.

    Частичные и функциональные индексы

    Частичные индексы покрывают только часть строк таблицы — это уменьшает размер индекса и ускоряет его обновление.

    -- Частичный индекс только по активным пользователям
    CREATE INDEX idx_users_active_email ON users (email)
    WHERE is_active = true;
    
    -- Функциональный индекс на результат выражения
    CREATE INDEX idx_users_lower_email ON users (lower(email));
    
    -- Теперь поиск без учёта регистра использует индекс
    SELECT * FROM users WHERE lower(email) = 'user@example.com';
    

    Частые ошибки

    Индекс на поле с низкой кардинальностью. Индекс по булевому полю или полю со статусом из трёх значений почти бесполезен — планировщик предпочтёт seq scan. Используйте частичный индекс.

    -- Плохо: кардинальность поля — 2 значения
    CREATE INDEX idx_users_is_admin ON users (is_admin);
    
    -- Лучше: частичный индекс только по нужному подмножеству
    CREATE INDEX idx_users_admins ON users (id) WHERE is_admin = true;
    

    Неправильный порядок колонок в составном индексе. B-Tree применяет колонки слева направо. Если запросы всегда фильтруют по status, он должен стоять первым.

    -- Плохо: запрос фильтрует только по status, индекс не используется полностью
    CREATE INDEX idx_orders_wrong ON orders (user_id, status);
    
    -- Правильно: наиболее часто используемый фильтр — первым
    CREATE INDEX idx_orders_right ON orders (status, user_id);
    

    Индекс не используется из-за неявного приведения типов. Если тип аргумента в запросе не совпадает с типом колонки, PostgreSQL не сможет использовать индекс.

    -- Плохо: phone хранится как VARCHAR, но передаётся число — приведение ломает индекс
    SELECT * FROM users WHERE phone = 79001234567;
    
    -- Правильно: тип аргумента совпадает с типом колонки
    SELECT * FROM users WHERE phone = '79001234567';
    

    Создание индексов без анализа реальных запросов. Перед созданием индекса всегда проверяйте план выполнения.

    -- Полный анализ с реальным выполнением запроса и статистикой буферов
    EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
    SELECT * FROM orders WHERE user_id = 42 AND status = 'pending';
    

    Заключение

    Правило выбора типа индекса в PostgreSQL простое — смотрите на тип данных и характер запросов:

    • B-Tree — универсальный выбор для сравнений и диапазонов
    • Hash — только проверка на равенство с высокой кардинальностью
    • GiST — геометрия, диапазоны, близость
    • GIN — JSONB, массивы, полнотекстовый поиск
    • BRIN — огромные таблицы с монотонными, последовательно вставляемыми данными

    Каждый индекс — это компромисс между скоростью чтения и стоимостью записи. Используйте pg_stat_user_indexes для поиска неиспользуемых индексов и EXPLAIN ANALYZE для проверки эффекта от новых.

    Иконка глаза1 039

    Комментарии

    0

    Постройте личный план изучения Neovim - практика и настройка до уровня Middle — бесплатно!

    Neovim - практика и настройка — часть карты развития Frontend, Backend, DevOps

    • step100+ шагов развития
    • lessons30 бесплатных лекций
    • lessons300 бонусных рублей на счет

    Бесплатные лекции

    Лучшие курсы по теме

    изображение курса

    React и Redux Toolkit

    Антон Ларичев
    AI-тренажерыAI-тренажеры
    Практика в студииПрактика в студии
    Гарантия
    Бонусы
    иконка звёздочки рейтинга4.8
    3 999 ₽ 6 990 ₽
    Подробнее
    изображение курса

    Zustand

    Антон Ларичев
    AI-тренажерыAI-тренажеры
    Практика в студииПрактика в студии
    Гарантия
    Бонусы
    иконка звёздочки рейтинга4.8
    3 999 ₽ 6 990 ₽
    Подробнее
    изображение курса

    Next.js - с нуля

    Антон Ларичев
    AI-тренажерыAI-тренажеры
    Практика в студииПрактика в студии
    Гарантия
    Бонусы
    иконка звёздочки рейтинга4.7
    3 999 ₽ 6 990 ₽
    Подробнее

    Похожие статьи

    Иконка аватараАнтон
    Иконка календаря01 октября 2026
    AI-инструментыDevOpsразработка+ 2middleИконка уровня middle

    Gemini CLI в России: как установить и настроить

    Установить Gemini CLI из России можно без VPN и без ухищрений — это обычный npm-пакет, он скачивается и запускается на любой машине. Упирается всё на следующем шаге: 18 июня 2026 года Google перестал обслуживать запросы Gemini CLI для бесплатных аккаунтов и подписчиков Google AI Pro и Ultra, а единственный оставшийся путь — вход по API-ключу — требует биллинга в регионе, где Россия не числится. Ниже разбираем, как агент ставится, как устроены три способа входа, почему ни один из них не доводи...

    Иконка чипа0
    Иконка глаза186
    Иконка комментариев0
    Картинка поста Git флоу для команды разработчиков: гайд по веткам и релизам
    Иконка аватараАнтон
    Иконка календаря30 сентября 2026
    gitgit-flowкомандная работа+ 2middleИконка уровня middle

    Git флоу для команды разработчиков: гайд по веткам и релизам

    Git флоу для команды разработчиков: разбираем Git Flow, GitHub Flow и trunk-based development — как выбрать модель веток и избежать конфликтов при совместной работе.

    Иконка чипа0
    Иконка глаза144
    Иконка комментариев0
    Иконка аватараАнтон
    Иконка календаря29 сентября 2026
    AI-инструментыClaude CodeDevOps+ 2middleИконка уровня middle

    Бесплатный аналог Cursor и Claude Code в России

    Короткий ответ: бесплатных аналогов много, и почти все они ставятся в России без ухищрений — Cline, Kilo Code, OpenCode, Qwen Code, Codex CLI распространяются с открытым исходным кодом, и за сам инструмент никто денег не берёт. Проблема в другом: своей модели у них нет. Платите вы не за агента, а за модель, к которой он ходит, и блокируется из России именно доступ к модели. Поэтому вопрос «чем заменить Cursor и Claude Code» почти всегда оказывается другим вопросом — где взять доступ к сильной модели без зарубежной карты. Ниже разберём, что из бесплатного реально работает, где оно упирается в потолок, и во сколько обходится не искать замену вообще. {{IMAGE_1}} alt: Схема: бесплатные клиенты-агенты Cline, Kilo Code, OpenCode, Qwen Code и платный доступ к модели за ними prompt: Flat vector diagram on dark background, two clearly separated zones. Left zone labeled "free" contains five small rounded cards representing code editor agents with terminal and sidebar icons. Right zone labeled "paid" contains a single large cloud icon representing an AI model, with a lock badge. Arrows go from all five cards to the single cloud. Purple and violet accent colors, thin white lines, no text labels, clean minimal tech illustration, 16:9

    Иконка чипа0
    Иконка глаза430
    Иконка комментариев1
    Иконка чипа0