Files
homework/mnoskov/postgresql/9. Оптимизация/3. Оптимизатор запросов/DQL_optimizer_pracitce.sql
T

165 lines
5.4 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
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 ANALYZE
SELECT name, age
FROM mnoskov.users
WHERE country = 'RU' AND age > 25;
-- Вариант Б
EXPLAIN ANALYZE
SELECT name, age
FROM mnoskov.users
WHERE age > 25 AND country = 'RU';
-- Выводят они один и тот же результат, потому что условия у них одинаковые
-- По скорости выполнения судя по планировщику тоже одинаковоы
-- Задание 2
-- Вариант 1
EXPLAIN ANALYZE
SELECT
u.name,
u.email,
o.order_date::date,
o.status
FROM
mnoskov.users u
JOIN
mnoskov.orders o ON u.id = o.user_id
WHERE o.status = 'refunded';
-- Вариант 2
EXPLAIN ANALYZE
SELECT
u.name,
u.email,
o.order_date::date,
o.status
FROM
mnoskov.orders o
JOIN
mnoskov.users u ON o.user_id = u.id
WHERE o.status = 'refunded';
-- Между первой и второй таблицей результаты одинаковые. Если в запросе нет никаких условий связанных с таблицами, то первой оптимизатор смотреть users, но если если условие по orders.status, то сначала он сканирует orders
-- Задание 3
EXPLAIN ANALYZE
SELECT name, email
FROM mnoskov.users
WHERE country = 'RU';
-- Тип сканирования: Seq Scan
-- Количество прочитанных строк: 1
-- Время выполнения примерно: 0.023 ms(+-5)
-- Задание 4
-- Запрос А
EXPLAIN ANALYZE
SELECT *
FROM mnoskov.users
WHERE country = 'RU';
-- Запрос Б
EXPLAIN ANALYZE
SELECT name, email
FROM mnoskov.users
WHERE country = 'RU';
-- Поскольку данных в таблице мало у меня время выполнения одинаковое, но могу предположить, что второй выполнился быстрее, тк у него в селекте два поля, а не вся таблица
-- Задание 5
EXPLAIN ANALYZE
SELECT
u.name, o.id, o.order_date
FROM
mnoskov.users u
JOIN
mnoskov.orders o ON u.id = o.user_id
WHERE
u.country = 'RU';
-- Читать начала с users, тк мы в where пишем условие для users, и быстрее сначала отсеять ненужных юзеров
-- Задание 6
SELECT u.name, COUNT(o.id) AS orders_count
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.country = 'Россия'
AND LOWER(u.name) LIKE '%алекс%'
GROUP BY u.name;
-- Его замедляет LOWER(не надо использовать функции), и думаю что LIKE(лучше использовать просто =), и ещэ group by по имени - это дольше чем по первичному ключу(надо группировать по ПК)
-- Задание 7
EXPLAIN ANALYZE
SELECT u.name, p.name AS product_name, oi.quantity
FROM users u
JOIN orders o ON u.id = o.user_id
JOIN order_items oi ON o.id = oi.order_id
JOIN products p ON oi.product_id = p.id
WHERE u.country = 'RU';
-- users -> orders -> order_items -> products - читает в таком порядке, потому что в where условие по users
-- Если убрать where, то будет - order_items -> users -> orders -> products
-- Как ускорить не знаю, может индексов добавть, но это пока не проходил
-- Задание 8
-- Вариант А
EXPLAIN ANALYZE
SELECT name, price
FROM mnoskov.products
WHERE category = 'Электроника'
AND price > 50000;
-- Вариант Б
EXPLAIN ANALYZE
SELECT *
FROM mnoskov.products
WHERE category = 'Электроника'
AND price > 50000;
-- Данных в таблицах мало, врем выполнения не оценить, но смотря просто со стороны понятно что выриант А будет быстрее, потому что у него пару колонок в селекте, а не вся таблица как в Б
-- Задание 9
-- Вариант коллег
SELECT *
FROM users
WHERE EXTRACT(YEAR FROM created_at) = 2026
AND LOWER(country) = 'россия'
AND age + 10 > 35;
-- Мой вариант
SELECT
id, name, age, is_active
FROM
mnoskov.users
WHERE
created_at BETWEEN '2026-01-01' AND '2027-01-02' AND
country = 'RU' AND
age > 45;
-- Мой вариант лучше потому что:
-- нет функций и мат. вычислений в where, все приведено к самому легкочитаемому формату
-- нет звездочки в select, а только то, что нужно
-- Задание 10
INSERT INTO users (id, name, age, email, country, created_at)
SELECT
g AS id,
'user_' || g AS name,
27 AS age,
'user_' || g || '@example.com' AS email,
'RU' AS country,
'2026-02-03' AS created_at
FROM generate_series(20001, 50000) AS g; -- GPT сделал запрос мне
SELECT * FROM mnoskov.users WHERE age IS NOT NULL;
-- Запрос 1
EXPLAIN ANALYZE
SELECT * FROM users WHERE age > 25;
-- Запрос 2
EXPLAIN ANALYZE
SELECT name, email FROM users WHERE age > 25;
-- Ну чето все равно не видна разница во времени выполнения, но по логике должен быть быстрее второй запрос