Как индекс ускоряет запрос (и как ускорить сам индекс)

В прошлом посте я рассказал про LATERAL и упомянул индексы. Напомню задачу: нужно найти самую свежую запись в огромной таблице по нескольким условиям.

Как задачу решали изначально max(date) from (select ... from where ...)

Представим базу данных как огромную библиотеку. Нам нужно найти книгу, изданную позже всех, авторы которой — поэты или драматурги 19-20 веков. Библиотекарь в данном случае ведет себя нерационально: он обходит всю библиотеку, вручную отбирает тысячи книг, а потом в этой горе ищет одну-единственную. Звучит не быстро...

Как ускорить процесс: 1. Подготовка навигации (Индекс) Создаем композитный индекс: indicator_type (жанр), date_type (эпоха), date DESC (дата в обратном порядке). Мы заранее проходим по библиотеке и клеим на обложки стикеры. Теперь не нужно открывать каждую книгу — мы видим жанр и эпоху сразу.

2. Готовим «стопки» книг Чтобы не искать «всё сразу», мы четко формулируем наборы:

SELECT * FROM (VALUES ('поэт'), ('драматург')) AS t(indicator) CROSS JOIN (VALUES ('19 век'), ('20 век')) AS d(dt_type) Получаем 4 конкретных набора. В индексе мы указали date DESC — это важный момент: книги в наших виртуальных стопках уже лежат в нужном порядке, самая свежая всегда сверху.

3. Включаем LATERAL Теперь мы не бегаем по залу. Мы подходим к каждой из 4-х готовых стопок, берем одну первую книгу и уходим.

CROSS JOIN LATERAL ( SELECT ss.date FROM bi.start_screen ss WHERE ss.indicator_type = params.indicator AND ss.date_type = params.dt_type ORDER BY ss.date DESC LIMIT 1 ) sub; Итог: Вместо того чтобы перерывать 400 000 книг, мы сравниваем всего 4 штуки.

Индексы — это заранее подготовленная навигация. При грамотном использовании они превращают хаотичный поиск в точечный маршрут. Есть, конечно, куча нюансов, но об этом — в других заметках. Связи: 📌 Что такое LATERAL и зачем он в JOIN?


В этом посте были ссылки, но мы их удалили по правилам Сетки