Files
homework/dmedvedev/10.4.Explain.sql
T
Dmitry Medvedev 4f56e71ef8 fix mistakes
2026-08-01 22:07:18 +05:00

157 lines
7.2 KiB
SQL
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
--Задача 1 — Читаем план
EXPLAIN
SELECT name, email
FROM users
WHERE id = 1;
Какой тип сканирования использует база?
--SeqScan - сканирование всей таблицы
Что означает строка `Index Cond: (id = 1)`?
-- Строка означает фильтрацию столбца по индексу, который есть в столбце id.
Почему база использует индекс, а не читает всю таблицу?
--В моем случае БД читает всю таблицу, но обычно если индексы расставлены верно и таблица больших размеров, то БД лучше использовать индексы для повышенной производительности.
----------
--Задача 2 — Seq Scan vs Index Scan
Почему в первом запросе используется Index Scan, а во втором может быть Seq Scan (если нет индекса на age)?
--Потому что Seq Scan сканирует таблицу полностью и ищет значения, а вот Index Scan нет необходимости сканировать всю таблицу, он отсекает по индексу.
----------
--Задача 3 — Замеряем время
1. Запиши **Execution Time**
--0.023 мс
2. Определи тип сканирования (Seq Scan или Index Scan)
--Seq Scan
3. Сколько строк вернул запрос?
--вернул 3 строки
----------
--Задача 4 — До и после индекса
Запиши Execution Time и тип сканирования.
--Seq Scan, 0.059 мс, после создания индекса запрос составил 0.026мс
Изменился ли тип сканирования?
-- Нет, не изменился, не могу понять почему.
Стал ли запрос быстрее? На сколько?
--Да, в 2 раза
Почему индекс помог?
--Потому что не пришлось искать по всей таблице.
----------
--Задача 5 — Анализируем JOIN
Какой тип JOIN использует база (Hash Join, Nested Loop, Merge Join)?
--Hash
С какой таблицы база начала чтение?
-- с users
Сколько времени занял весь запрос?
--execution time 0.032ms
----------
--Задача 6 — Почему медленно?
1. Выполни запрос и посмотри на план
--посмотрел
2. Использует ли база индекс?
--нет, используется seq scan
3. Почему НЕТ? (даже если индекс на email есть)
--Думаю, потому что также используется функция LOWER внутри WHERE
4. Как исправить запрос, чтобы индекс заработал?
CREATE INDEX idx_email ON users(LOWER(email))
----------
--Задача 7 — Функции убивают индексы
Какой запрос работает быстрее?
--тот где нет дополнительной математики в условии
Почему первый запрос НЕ может использовать индекс на `age`?
--потому что появилась функция
Как правильно переписать запрос А?
-- убрать функцию из условия:
EXPLAIN ANALYZE
SELECT * FROM users WHERE age > 35;
----------
--Задача 8 — Диагностика медленного запроса
1. Почему функция `EXTRACT()` — плохая идея?
--потому что она мешает оптимизатору применить индекс.
2. Как переписать условие WHERE без функции?
--добавлением граничных условий что-то по типу created_at>='2026-01-01' AND created_at<'2027-01-01'
3. Будет ли использоваться индекс на `created_at` в текущем виде?
--нет, по описанным выше условиям
----------
--Задача 9 — SELECT * против конкретных колонок
Какой запрос работает быстрее?
-- запрос Б, там где выбираются не все столбцы
Почему второй может быть эффективнее (даже если тип сканирования одинаковый)?
--потому что объем обработанной информации меньше
В каких ситуациях разница будет особенно заметна?
--когда вся таблица изначально состоит из множества столбцов (более 10), а вт втором запросе мы берем только пару И когда количество строк очень большой.
----------
--Задача 10 — Оптимизируем JOIN с условием
1. Выполни запрос и посмотри на план
посмотрел
2. В каком порядке база читает таблицы?
БД читает таблицы в порядке, который является наименее затратным. Сначала идет отфильтровывание по условию,далее создается хэш таблица и хэш соединение, соединение по индексу.
3. Сколько строк проходит через каждый JOIN?
У меня здесь только 1 hash join - там 5 строк. Но сразу скажу, что одно из условий я удалил, так что у меня осталось только одно условие с category.
4. Можно ли оптимизировать? (Подсказка: подумай про индексы на `country` и `category`)
Я добавил индекс на category, поменялось количество hash join, стало 2.
Но сканирование не изменилось на индекс. Видимо, это связано с тем, что оптимизатору проще проходить по всей таблице, чем искать по индексу ввиду того, что таблица сама по себе не большая.
----------
--Задача 11 — Найди и исправь
Основной запрос
EXPLAIN ANALYZE
SELECT *
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE LOWER(u.name) LIKE '%иван%'
AND EXTRACT(MONTH FROM o.order_date) = 1
AND u.age + 10 > 35;
Оптимизированный
EXPLAIN ANALYZE
SELECT u.name, o.order_date, u.age
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.name LIKE '%иван%'
AND o.order_date >= '2024-01-01'
AND o.order_date < '2024-02-01'
AND u.age > 25;
По моим данным ожидаемое кол-во строк = 0, поэтому и запросы отрабатываются быстро = 0.03 мс.