Как планировщик запросов СУБД решает, использовать ли индекс?

Ответ

Планировщик запросов (query planner) — это компонент СУБД, который выбирает наиболее эффективный способ выполнения SQL-запроса. Решение об использовании индекса принимается на основе анализа нескольких факторов:

  1. Селективность индекса. Насколько уникальны значения в столбце. Индекс наиболее полезен, если он позволяет отфильтровать большую часть данных (высокая селективность, например, по user_id или email). Если значения часто повторяются (низкая селективность, например, столбец gender), полный перебор таблицы может быть быстрее.

  2. Условия запроса. Индексы активно используются для ускорения операций WHERE, JOIN, ORDER BY и GROUP BY по индексированным полям.

  3. Размер таблицы. Для очень маленьких таблиц планировщик может предпочесть полное сканирование (Full Table Scan), так как накладные расходы на обращение к индексу могут превысить выгоду от его использования.

  4. Статистика данных. СУБД собирает и хранит метаданные о распределении данных в таблицах (гистограммы). Планировщик использует эту статистику для оценки, сколько строк вернет тот или иной узел плана.

  5. Стоимость операций. Планировщик оценивает "стоимость" (в условных единицах CPU и I/O) различных планов выполнения. Он сравнивает стоимость полного сканирования таблицы со стоимостью сканирования по индексу (Index Scan) и выбирает план с наименьшей предполагаемой стоимостью.

Чтобы увидеть, какой план выбрал планировщик, используется команда EXPLAIN. Пример для PostgreSQL:

-- Если есть индекс на email, в плане, скорее всего, будет "Index Scan"
EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'test@example.com';

Ответ 18+ 🔞

А, слушай, про эту вашу магию под капотом, про планировщик запросов! Это ж тот самый умник в базе данных, который решает, как твой запрос выполнять, чтобы не облажаться. Представь себе такую картину: ты пишешь SELECT * FROM users WHERE email = 'test@example.com', а он, этот планировщик, сидит, чешет репу и думает: «Ну что, блядь, как бы нам это сделать побыстрее?»

Вот на что он смотрит, этот хитрожопый аналитик:

  1. Селективность индекса. Грубо говоря, насколько уникальны данные в столбце. Если у тебя индекс на user_id — это охуенно, отфильтрует почти всё. А вот если на gender (где всего два-три значения), то это пиздец как неселективно. Планировщик посмотрит и скажет: «Да похуй, проще всю таблицу прочитать, чем по этому индексу скакать, как мартышка».

  2. Условия запроса. Ну тут всё логично, ёпта. WHERE, JOIN, ORDER BY — если поля проиндексированы, он попытается это использовать. Но если ты пишешь какую-то хуйню вроде WHERE UPPER(email) = 'TEST', то прощай, индекс, тебя как не было.

  3. Размер таблицы. Вот у тебя табличка на 100 строк. Планировщик прикинет: «Овердохуища работы — открыть индекс, найти там ссылки, потом по ним строки вытаскивать... Да я её, блядь, целиком за милую душу просканирую!». Для мелких таблиц полное сканирование (Full Table Scan) — это часто норма.

  4. Статистика данных. А вот это, сука, ключевой момент! База не дура, она постоянно собирает справки о таблицах: сколько там строк, как значения распределены. Планировщик смотрит на эти гистограммы и говорит: «Ага, значение test@example.com встречается один раз на миллион записей — значит, индекс рулит». Если статистика устарела — он может принять идиотское решение. Волнение ебать!

  5. Стоимость операций. Всё сводится к деньгам, вернее, к «стоимости» в единицах CPU и чтения с диска. Он просчитывает кучу планов: «Вариант А — Index Scan, стоимость 15. Вариант Б — Full Scan, стоимость 250. Ну ясень пень, выбираем А, нехуй тут думать».

И как же, блядь, заглянуть ему в карты и узнать, что он там надумал? Да очень просто — командой EXPLAIN. А если добавить ANALYZE, то он не только план покажет, но и реально выполнит запрос, подсчитав время. Прямо как рентген для запроса!

-- Если индекс на email есть и он годный, в плане будет красота типа "Index Scan"
EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'test@example.com';

Выполнишь это — и всё станет ясно: использовал ли он индекс или пошёл в разнос по всей таблице. Иногда смотришь на план и думаешь: «Сам от себя охуел... Почему он выбрал этот пиздец?». А потом вспоминаешь, что статистику три года не обновлял. Вот и весь секрет, в рот меня чих-пых!