Вопросы по SQL и базы данных
От SELECT до оконных функций, индексов и уровней изоляции в PostgreSQL. Закрывает SQL-секцию бэкенд-собеса: и задачи на запросы, и вопросы «почему тормозит».
Проверьте себя: тест по SQL и базам данных
20 вопросов, 10 минут, уровень junior, middle или senior
SELECT и фильтрация
Порядок выполнения запроса, WHERE, NULL, сортировка и пагинация.
Урок: SELECT и фильтрация за 6 минут 6 мин- Псевдоним из SELECT в WHERE
- Приоритет AND и OR
- Границы BETWEEN
- Почему тормозит большой OFFSET
- DISTINCT и NULL
- Сравнение с NULL через =
- IS DISTINCT FROM
- Keyset-пагинация
Ещё 19 вопросов и задач
- Трёхзначная логика в SQL
- Логический порядок выполнения SELECT
- NOT IN со списком, где есть NULL
- Где окажутся NULL при сортировке
- Порядок строк без ORDER BY
- Как работает NULL в SQL
- Пагинация больших списков
- Самые дешёвые товары с учётом ничьих
- Подстановка значений вместо NULL
- Список городов без повторов
- Заказы за месяц без отменённых
- Почта на mail.ru в любом регистре
- Ценовые сегменты через CASE
- Подписки, которые закончатся на неделе
- Все, кто не из Москвы, включая NULL
- Клиенты без email
- Клиенты из Москвы
- Товары в диапазоне цен с сортировкой
- Вторая страница каталога
JOIN
INNER, LEFT, FULL, CROSS, self join и ловушки с условиями в ON и WHERE.
Урок: JOIN за 6 минут 6 мин- Как найти клиентов без заказов
- Сколько строк даст CROSS JOIN
- Размножение строк при двух JOIN
- Anti-join
- Self join
- Semi-join
- Что делает FULL JOIN
- Число строк после LEFT JOIN
Ещё 18 вопросов и задач
- Фильтр по правой таблице LEFT JOIN в WHERE
- Чем опасен NATURAL JOIN
- NULL в ключе соединения
- RIGHT JOIN через LEFT
- Сумма в отчёте задвоилась
- Виды JOIN
- Пары клиентов из одного города
- Сотрудники, которые получают больше руководителя
- Задвоение сумм при двух JOIN
- Товары, которые ни разу не заказывали
- Состав оплаченных заказов
- Сверка платежей с банком через FULL JOIN
- Сетка дни на регионы с нулями
- Все клиенты и их оплаченные заказы
- Клиенты без заказов
- Сотрудник и его руководитель
- Заказы с именем клиента
- Что покупала Дина
GROUP BY и агрегаты
COUNT, SUM, AVG, GROUP BY, HAVING и поведение NULL в агрегатах.
Урок: GROUP BY и агрегаты за 5 минут 5 мин- Агрегат в WHERE
- AVG и NULL
- COUNT(DISTINCT) и NULL
- COUNT(*) против COUNT(колонка)
- Поиск дублей
- Три формы COUNT
- FILTER в агрегатах
- HAVING
Ещё 21 вопрос или задача
- NULL в GROUP BY
- COUNT(*) после LEFT JOIN
- Колонка не из GROUP BY
- Агрегаты и NULL
- WHERE и HAVING
- SUM на пустом наборе
- Условие без агрегата: WHERE или HAVING
- Средняя зарплата в больших отделах
- Доля отменённых заказов в процентах
- Дубли email без учёта регистра
- Медиана зарплаты по отделам
- Заказы и выручка по месяцам
- Клиенты, покупавшие из разных категорий
- Состав заказа одной строкой
- Выручка по категориям
- Итоговая строка через ROLLUP
- Клиенты, потратившие больше 10 000
- Количество клиентов по городам
- Сотрудники по отделам, включая пустые
- Сумма каждого заказа
- Оплаченные и отменённые по клиентам
Подзапросы и CTE
Скалярные и коррелированные подзапросы, EXISTS, IN, WITH и рекурсия.
Урок: Подзапросы и CTE за 6 минут 6 мин- Полный путь категории в дереве
- Клиенты, у которых все заказы оплачены
- Дни без продаж по регионам
- Цепочка руководителей вверх по дереву
- Дороже любой книги: ALL против MAX
- Категория с максимальной выручкой
- Два последних заказа каждого клиента через LATERAL
- Дороже среднего по своей категории
Ещё 18 вопросов и задач
- Средний чек оплаченных заказов
- Клиенты без оплаченных заказов
- Последний заказ каждого клиента
- Все подчинённые с уровнем
- Что такое коррелированный подзапрос
- Материализуются ли CTE в PostgreSQL
- Что писать в SELECT внутри EXISTS
- Коррелированный подзапрос
- CTE
- Рекурсивный CTE
- Зачем LATERAL
- NOT IN по подзапросу с NULL
- Когда останавливается рекурсивный CTE
- Скалярный подзапрос вернул две строки
- Скалярный подзапрос без строк
- EXISTS против IN
- Дерево категорий одним запросом
- UNION и UNION ALL
Оконные функции
ROW_NUMBER, RANK, LAG, накопительные суммы и рамка окна.
Урок: Оконные функции за 7 минут 7 мин- Через сколько дней второй заказ
- Какие дубли удалить, оставив свежую запись
- Самый высоко- и низкооплачиваемый в отделе
- Самая длинная серия дней подряд
- Рост выручки к прошлому месяцу
- Скользящее среднее выручки за 3 дня
- Длинные перерывы между оплатами
- Разбиение кликов на сессии
Ещё 20 вопросов и задач
- Место по зарплате в отделе
- Разница выручки с прошлым днём
- Нарастающий итог продаж
- Доля зарплаты в фонде отдела
- Топ-2 по зарплате в каждом отделе
- Окно поверх агрегата
- Нарастающий итог при одинаковых датах
- Пустой OVER()
- Рамка окна
- ROW_NUMBER, RANK, DENSE_RANK
- Оконная функция
- Оконная функция в WHERE
- LAG у первой строки
- Ловушка LAST_VALUE
- Скользящее среднее за 3 дня
- Как NTILE делит строки
- RANK на равных значениях
- Рамка окна
- Топ-N в каждой группе
- Окно против GROUP BY
Индексы
B-tree, составные, частичные, покрывающие индексы, GIN и когда индекс не помогает.
Урок: Индексы за 7 минут 7 мин- Индекс на живой базе
- Чем платим за индексы
- Покрывающий индекс
- Индекс на внешнем ключе
- B-tree индекс
- Покрывающий индекс
- Селективность
- Функция над колонкой и индекс
Ещё 20 вопросов и задач
- Индекс для jsonb
- Правило левого префикса
- Поиск по подстроке
- Почему не используется индекс по статусу
- Частичный индекс
- Порядок колонок в составном индексе
- Почему индекс не используется
- Составной индекс под фильтр и сортировку
- Index Only Scan и visibility map
- Тип индекса под задачу
- Перепиши поиск по email под функциональный индекс
- Перепиши поиск по началу названия под индекс
- Перепиши фильтр ts::date под индекс по времени
- Почему индекс по created_at не используется
- Index Only Scan с большим Heap Fetches
- Когда BRIN-индекс хорош
- Запретить пересекающиеся бронирования в базе
- GIN для jsonb: jsonb_ops или jsonb_path_ops
- Как выбрать тип индекса в PostgreSQL
- Раздутый индекс на проде
Транзакции и изоляция
ACID, аномалии, уровни изоляции, MVCC и блокировки в PostgreSQL.
Урок: Транзакции и изоляция за 8 минут 8 мин- Advisory-блокировки в PostgreSQL
- Как избежать deadlock при переводах
- Взаимоблокировки: как ловить и предотвращать
- Долгая транзакция и раздувание таблиц
- MVCC и VACUUM в PostgreSQL
- VACUUM или VACUUM FULL на проде
- Зачем нужна заморозка и что такое wraparound
- Что делает PostgreSQL при deadlock
Ещё 14 вопросов и задач
- Уровень изоляции по умолчанию в PostgreSQL
- Как обеспечивается Durability
- ACID
- MVCC
- Write skew
- Потерянное обновление
- MVCC и блокировки чтения
- Non-repeatable read
- Read Uncommitted в PostgreSQL
- Фантомы на Repeatable Read в PostgreSQL
- Serializable и повтор транзакций
- Очередь задач на таблице
- Списание с баланса без гонок
- Уровни изоляции
Проектирование и нормализация
Ключи, связи, нормальные формы, денормализация и ограничения.
Урок: Проектирование и нормализация за 6 минут 6 мин- Нарушение второй нормальной формы
- Транзитивная зависимость
- Денормализация
- Нормализация
- Суррогатный ключ
- Связь многие ко многим
- Тип для денег
- ON DELETE CASCADE
Ещё 15 вопросов и задач
- Цена в позиции заказа
- Уникальность с мягким удалением
- Нормализация и денормализация
- Схема заказов интернет-магазина
- timestamp или timestamptz
- Уникальность только в коде
- Случайные UUID и индекс
- Новая колонка с DEFAULT на большой таблице
- CREATE INDEX CONCURRENTLY: подводные камни
- Удалить 300 млн старых строк из живой таблицы
- ALTER TABLE повесил прод на пустом месте
- NOT NULL на огромной таблице без простоя
- Удаление старых данных: DELETE или партиции
- Первичный ключ в партиционированной таблице
- Миграции схемы без простоя
EXPLAIN и оптимизация
Чтение плана, виды сканов и соединений, статистика, N+1 и пагинация.
Урок: EXPLAIN и оптимизация за 8 минут 8 мин- Bitmap Heap Scan
- Фильтр по дню и индекс
- Оценка строк против факта
- EXPLAIN и EXPLAIN ANALYZE
- Hash Join
- Index Only Scan
- pg_stat_statements
- Как читать loops
Ещё 29 вопросов и задач
- Проблема N+1
- Когда хорош Nested Loop
- С чего начать оптимизацию базы
- Всегда ли Seq Scan плохо
- Сортировка на диске
- Проблема N+1
- Запрос тормозит на проде
- EXPLAIN ANALYZE и расширенная статистика
- Последние заказы: какой узел в плане
- Чтение плана: полный просмотр и фильтр
- Сортировка ушла на диск: план и настройка
- Узлы плана и что они делают
- Порядок разбора медленного запроса
- Перепиши подзапрос в SELECT на JOIN с GROUP BY
- Перепиши DISTINCT после JOIN на EXISTS
- Перепиши фильтр из HAVING в WHERE
- Перепиши NOT IN, который вернул пусто
- Перепиши OFFSET-пагинацию на keyset
- Перепиши фильтр по месяцу под индекс
- Оценка 2 тысячи, факт 10 тысяч: зависимые колонки
- Что значит Batches: 2 у узла Hash
- Как читать loops во вложенном цикле
- Сколько строк вернул параллельный скан
- Seq Scan при выборке 90% строк
- Почему в плане Bitmap Heap Scan, а не Index Scan
- Почему COUNT(*) на большой таблице медленный
- Подготовленный запрос внезапно стал медленным
- Перекошенная колонка и неверные оценки
- work_mem = 1GB и падение базы по памяти
NoSQL и выбор хранилища
Документные, key-value, колоночные БД, Redis и когда брать что.
Урок: NoSQL и выбор хранилища за 6 минут 6 мин- Запросы в Cassandra
- Для чего ClickHouse
- Роль Elasticsearch
- Обратный индекс
- Репликация
- Шардирование
- Горячий шард
- jsonb вместо документной базы
Ещё 13 вопросов и задач
- Кворум R + W > N
- Почему команды Redis атомарны
- Сохранность данных в Redis
- Простая блокировка в Redis
- SQL или NoSQL
- Redis в бэкенде
- Физическая или логическая репликация
- PgBouncer в режиме transaction pooling
- Записал в мастер, не нашёл на реплике
- Репликация и отказоустойчивость PostgreSQL
- Шардирование PostgreSQL
- Что гарантирует синхронная репликация
- Зачем пулер, если в приложении уже есть пул