linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
Intro
Lessons
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Главы
  • How it worksскоро
  • Уроки
  • База знаний
  • Собеседование
home/postgres/kb/Индексы/sargability

kb/indexes ── Индексы ── intermediate

Sargability: почему индекс не используется

Условие sargable, если индекс по колонке к нему применим. Каст или функция над колонкой (created::date, lower(email)) делают его не-sargable - индекс игнорируется, план уходит в Seq Scan. Лечение - переписать или индекс по выражению.

view as markdownaka: sargable, index-not-used, function-on-column

«Индекс есть, а не используется» чаще всего значит, что условие не-sargable: колонка спрятана под функцией или кастом.

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

sql
-- не-sargable: индекс по created не подходит → Seq Scan
WHERE created::date = '2024-01-01'
-- sargable: диапазон по самой колонке → индекс работает
WHERE created >= '2024-01-01' AND created < '2024-01-02'

created::date оборачивает колонку в функцию; индекс построен по значениям created, а сравнивается результат приведения.

Функция над колонкой - то же

sql
WHERE lower(email) = 'a@b.c'   -- индекс по email не подходит

Два выхода: переписать без функции или индекс по выражению:

sql
CREATE INDEX ON users (lower(email));

Sargability ортогональна operator class

Даже если оператор поддержан методом доступа (см. operator-classes), не-sargable условие индекс не использует. Сначала условие должно быть sargable (колонка не под функцией), потом оператор - в operator class.

Как заметить

В EXPLAIN ANALYZE - Seq Scan (см. access-methods) там, где ждёшь индекс, и большое расхождение estimated/actual rows. Типичные виновники: каст, функция, неявное приведение типа. Проектирование индексов - в index-design.

§ команды

bash
WHERE col >= d AND col < d + 1

Sargable-диапазон вместо col::date = d

bash
CREATE INDEX ON t (lower(col));

Индекс по выражению, когда условие по функции

§ см. также

  • index-designПроектирование индексовИндекс - отсортированный список. Составной (a,b,c) работает по префиксу слева направо, не по средней колонке. Покрывающие (INCLUDE), частичные (WHERE) и по выражению сужают работу; лишние индексы - налог на запись.
  • operator-classesOperator classes и выбор индексаИндекс работает не «на колонке», а для конкретных операторов над ней. Связь тип+оператор+метод доступа задаёт operator class. Через каталог pg_amop можно узнать, какой AM поддерживает оператор: @> знают gin и gist, не btree.
  • btree-structureB-tree: структура и спускB-tree - сбалансированное дерево из 8-КБ страниц: meta page указывает на корень, внутренние страницы хранят разделители и downlink, листья - ключ и ctid. Большой fanout даёт 3-4 уровня на миллиарды строк.
  • access-methodsМетоды доступа: Seq, Index, Bitmap, Index-OnlyЧетыре способа достать строки: Seq Scan (всё подряд), Index Scan (мало строк, random I/O), Bitmap Heap Scan (средняя доля, страницы пачкой), Index-Only Scan (данные из индекса, если visibility map подтверждает).
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки