Почему SQL до сих пор управляет всем
SQL декларативен — ты описываешь нужное множество строк, а движок сам решает, как его достать. Именно это разделение позволило ему пережить 50 лет и каждую волну NoSQL.
Ты приходишь в компанию. Фронтенд уже на третьем фреймворке, бэкенд переписали с Ruby на Go, очередь сообщений меняли дважды. Нетронутым с 2009 года осталось одно: SQL, который читает таблицу orders. Новые языки умирают за десятилетие; этот SELECT переживёт твой срок в компании. Этот урок — о том, почему. К концу ты поймёшь одну идею, которая делает SQL непобедимым, — и одну привычку, которая убивает производительность в любом языке, работающем с базой.
Декларативный, а не императивный
В большинстве языков ты пишешь как: пройди по массиву, сравни каждый элемент, добавь совпадения в новый список. SQL — наоборот. Ты пишешь что хочешь и молчишь о том, как:
SELECT name, email
FROM users
WHERE country = 'JP'
ORDER BY created_at DESC
LIMIT 10;Ты не написал ни одного цикла. Не сказал «используй индекс по country», «сортируй quicksort» или «читай диск страницами по 8 КБ». Ты описал множество строк — японские пользователи, новейшие сверху, первые десять — и отдал задачу движку. Postgres разбирается с остальным: какой индекс взять, сортировать в памяти или сбросить на диск, сколько CPU-воркеров бросить на запрос.
У этого разделения есть имя: запрос — это логика (что), план — физика (как). Логический слой твой. Физический — планировщика. Следующий урок вскрывает планировщик; пока важно лишь то, что эта стена существует.
Почему это и есть долговечная идея
Поскольку ты не закодировал как, движок волен это менять. Тот же SELECT, что сканировал таблицу на 10 000 строк в 2009-м, сегодня идёт по B-tree индексу (древовидная структура, по которой Postgres ищет строку за O(log n) шагов) на 500 миллионах строк в 2026-м — тот же текст, совершенно другое физическое выполнение. Добавь индекс сегодня вечером — и завтрашний запрос станет в 600 раз быстрее без единой правки кода. Попробуй это с написанным вручную циклом.
Именно поэтому SQL пережил десятилетие NoSQL. Документные и key-value хранилища выиграли отдельные битвы (масштабирование записи, схемалесс-блобы), но большинство из них отрастили язык запросов, подозрительно похожий на SQL, потому что декларативную модель действительно трудно превзойти в вопросе «дай строки, подходящие под условие, соединённые с теми, сгруппированные и отсортированные». Сам Postgres впитал лучшую идею NoSQL — JSONB-документы — не отказавшись от реляционного ядра (встретишь это в разделе 06).
Мышление множествами, а не строками
Спроси себя: когда твой ORM шлёт 80 запросов, чтобы отрисовать одну страницу, — это проблема фреймворка или проблема мышления? Это проблема мышления. SQL работает с множествами, целиком и сразу, а не построчно. Здесь нет «текущей строки», как в цикле. WHERE концептуально применяется ко всему множеству как бы параллельно; JOIN — это комбинация двух множеств; GROUP BY сворачивает множество в корзины.
Практическое следствие: написать в приложении цикл, который шлёт по одному запросу на строку — паттерн N+1 запросов — самая частая ошибка производительности в продакшне. Один запрос на 1000 строк — это один round trip (сетевой туда-обратно); 1000 запросов по одной строке — это 1000 round trip’ов и часто в 100 раз медленнее. Весь смысл SQL — протолкнуть операцию над множеством вниз, в движок, а не тянуть строки наверх и крутить цикл в своём коде.
▸Почему это работает
Почему «лучший» язык не заменил SQL? Несколько пытались — LINQ, ORM, GraphQL, парад NoSQL-DSL. Каждый полезен, но любой из них, когда запрос становится нетривиальным, либо компилируется вниз в SQL, либо плохо переизобретает join’ы и агрегацию. За декларативной реляционной моделью стоит 50 лет исследований оптимизаторов; новому языку мало приятного синтаксиса — ему нужно заново вывести стоимостный планировщик. Этот ров и есть причина, по которой «просто выучи SQL» — всё ещё самый рычажный навык работы с данными в 2026 году.
Что значит, что SQL декларативен?
Приложение грузит 1 заказ, затем шлёт по запросу на каждую позицию, чтобы загрузить их. 80 позиций = 81 запрос. Как это называется и почему медленно?
Заполни пропуск: SQL для базы данных — то же, что заказ в ресторане для кухни. Ты говоришь, какое блюдо хочешь; ты не указываешь, какую _______ берёт повар и в каком порядке делает шаги.
- 01В одном предложении: чем декларативный SQL-запрос отличается от императивного кода?
- 02Почему один и тот же текст SQL может стать в 600 раз быстрее спустя годы без правок?
- 03Что такое паттерн N+1 запросов и в чём фикс через множества?
SQL декларативен: ты пишешь, какое множество строк хочешь, а движок решает, как его произвести. Это разделение логического запроса и физического плана — долговечное ядро языка: оно позволяет одному неизменному SELECT продолжать ускоряться по мере добавления индексов и роста данных, и именно поэтому SQL пережил эпоху NoSQL (впитав её лучшие идеи, вроде JSONB). Установка, которую стоит принять сейчас: мысли множествами, которые движок обрабатывает целиком, а не построчными циклами — построчная привычка порождает антипаттерн N+1, самый частый баг производительности в продакшн-коде. Теперь, когда ты заметишь у себя в коде цикл с запросом внутри, ты сразу поймёшь: это N+1 — схлопни его в один запрос над множеством и отдай работу движку.
Что-то непонятно?
Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.