План выполнения запроса ч. 2

Давайте разберем эту историю на примере базового запроса SELECT * FROM orders WHERE order_date = '2024-01-01';

Если выполнить команду EXPLAIN (в PostgreSQL, MySQL, Oracle и других СУБД), мы получим что-то вроде: Seq Scan on orders (cost=0.00..35.50 rows=5 width=100) Filter: (order_date = '2024-01-01')

Seq Scan (Sequential Scan): База данных просканирует всю таблицу orders. Это неэффективно для больших таблиц. • Cost: Оценка стоимости операции — чем выше, тем сложнее запрос. • Rows: Оценка количества строк, которые вернёт запрос. • Filter: Какой фильтр применён.

Если бы был индекс на order_date, запрос мог бы использовать Index Scan вместо полного сканирования таблицы.

Как интерпретировать план выполнения?

1. Типы сканирования: • Seq Scan: Последовательное сканирование таблицы. Медленно на больших таблицах. • Index Scan: Использует индекс, значительно быстрее для фильтров. • Bitmap Index Scan: Сканирование индекса для поиска подходящих строк, объединяя их в блоки.

2. Объединение данных (JOIN): • Nested Loop: Перебирает каждую строку одной таблицы и ищет совпадения в другой (подходит для небольших наборов данных). • Hash Join: Создаёт хэш-таблицу из одной таблицы, затем ищет совпадения. Быстро для больших таблиц. • Merge Join: Сортирует обе таблицы и объединяет их по порядку. Эффективно для уже отсортированных данных.

3. Операции сортировки: • Sort: Указывает, что данные сортируются, что может быть дорогостоящей операцией.

4. Оценка стоимости: • Общая стоимость включает чтение данных с диска, использование памяти и процессора.

Как сделать запросы эффективнее?

1. Используйте индексы. • Создайте индексы на столбцах, которые часто участвуют в фильтрации, сортировке или JOIN. CREATE INDEX idx_order_date ON orders(order_date); 2. Пишите запросы проще. • Разделяйте сложные запросы на несколько шагов. 3. Не выбирайте лишние данные. • Вместо SELECT * выбирайте конкретные столбцы: SELECT order_id, order_date FROM orders; 4. Изучайте план выполнения. • Перед оптимизацией всегда анализируйте, какие операции занимают больше всего ресурсов.

Интересные моменты из реальной практики

1. Проблема с JOIN В одной из задач JOIN двух больших таблиц занимал часы. После анализа плана выполнения понял, что надо прикрутить индексы. После их добавления запрос стал выполняться пару минут.

2. Over-indexing Слишком много индексов может замедлить операции INSERT и UPDATE. Анализ плана выполнения помогает понять, какие из них реально используются.

Важный поинт 1 Оптимизатор не всегда прав. Иногда оптимизатор выбирает неэффективный план. В таких случаях можно использовать хинты для принудительного выбора

Важный поинт 2 Вы как аналитик, оооочень редко будете работать прям с тем чтобы изучать план запроса и искать как его сделать лучше.

Обычно запросы не супер большие, либо под них есть удобные таблицы. И даже если вы не оптимизированно напишите запрос он будет крутиться ну пусть 10 минут вместо каких-нибудь 3. (Опять же ситуации разные могут быть)

План выполнения запроса ч. 2 | Сетка — социальная сеть от hh.ru План выполнения запроса ч. 2 | Сетка — социальная сеть от hh.ru