План выполнения запроса ч. 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. (Опять же ситуации разные могут быть)
· 04.04.2025
А ещё для оптимизации очень удобно пользоваться временными таблицами. Время обработки сокращается в разы.
0
ответить
коммент скрыт — часть юзеров считает его токсичным или некорректным
коммент удалён
· 06.04.2025
Хороший поинт
0
ответить
коммент скрыт — часть юзеров считает его токсичным или некорректным
ответ удалён