На одном собеседовании меня спросили про VIEW. Я ответил честно: в живых проектах они мне почти не попадались; для агрегатов надёжнее держать отдельную таблицу; а сами представления — вещь настолько нишевая, что за карьеру пригождались считанные разы. Разделение прав, долгие миграции, совместимость со старым ПО — вот и весь список. Ответ приняли прохладно. Один из собеседников сказал: «Ничего ты не понимаешь во VIEW» — и все посмеялись.

Прошло много времени. VIEW в моём коде так и не прибавилось, а вопрос остался, а вдруг с тех пор всё изменилось? Движки вышли новые. Поэтому я поднял MySQL 8.4 и PostgreSQL 17, залил одинаковые данные и прогнал основные сценарии один за другим.

Стенд

Docker Compose, MySQL 8.4.11 и PostgreSQL 17.11, схема интернет‑магазина: заказы, позиции, платежи, справочник продавцов. Данные детерминированные и побайтово одинаковые в обеих базах — миллион заказов, два миллиона позиций, 780 тысяч платежей, сто продавцов, даты за 21 месяц. Набор представлений зеркальный, простая обёртка, дневной агрегат, каскад из трёх уровней, ловушка с ORDER BY внутри, в PostgreSQL дополнительно материализованная view с уникальным индексом.

Измеряем серверное время, в MySQL корневой actual time из EXPLAIN ANALYZE, а в PostgreSQL Execution Time. Два прогрева, семь замеров, берём медиану. Само измерение увеличивает время мелких запросов в разы, поэтому сравнивать имеет смысл только одинаковые запросы. Сравнивать абсолютные миллисекунды на другой машине не имеет смысла. Две настройки памяти, у PostgreSQL work_mem дефолтные 4 МБ, у MySQL temptable_max_ram 1Гб. Окно запросов везде одинаковое — июнь 2026-го, продавец с ID 42.

Простая view не потребляет дополнительных ресурсов

Обёртка над orders без агрегации, полторы‑две миллисекунды в обеих СУБД, разброс в пределах шума, планы совпадают с планами прямого запроса. MySQL сливает определение с запросом (алгоритм MERGE), PostgreSQL разворачивает view правилом перезаписи ещё до планировщика. Оптимизатор просто не видит, что вы обратились к представлению.

Получаем скучный результат, как лучший из возможных. Переиспользуемый фильтр и контракт чтения view ничего не стоит.

Один CAST, и view дороже в тринадцать раз

CREATE VIEW v_merchant_daily AS
SELECT o.merchant_id,
       CAST(o.created_at AS DATE) AS day,
       COUNT(*)                   AS orders_cnt,
       SUM(o.amount_total)        AS revenue
FROM orders o
WHERE o.status IN ('paid', 'shipped', 'completed')
GROUP BY o.merchant_id, CAST(o.created_at AS DATE);

Запрос поверх неё — ровно то, что напишет любой:

SELECT * FROM v_merchant_daily
WHERE merchant_id = 42
  AND day >= '2026-06-01' AND day < '2026-07-01'
ORDER BY day;

PostgreSQL отдаёт это за 24.5 мс, а тот же результат прямым запросом к таблице — за 1.85 мс. Разница в тринадцать раз на ровном месте.

Моя первая версия объяснения была такая же, как в половине статей про view: «агрегат считается до фильтра, движок группирует всю таблицу, а потом отбрасывает лишнее». Я открыл план и оказался неправ.

GroupAggregate (actual time=26.702..26.897 rows=30)
  ->  Sort (rows=469)
      ->  Bitmap Heap Scan on orders o (actual time=3.661..26.505 rows=469)
            Recheck Cond: (merchant_id = 42)
            Filter: (status = ANY (...)) AND ((created_at)::date >= '2026-06-01') AND ...
            Rows Removed by Filter: 9531
            Heap Blocks: exact=8929
            Buffers: shared hit=8971
            ->  Bitmap Index Scan on idx_orders_merchant_created (rows=10000)
                  Index Cond: (merchant_id = 42)

Никакой агрегации всей таблицы. Оба предиката уехали под GROUP BY, до сканирования, планировщик умеет проталкивать условия по колонкам группировки, и merchant_id, и day ими являются. Полностью агрегируются 469 строк, так же как в прямом запросе.

Разница в другой строчке. Rows Removed by Filter: 9531 и Heap Blocks: exact=8929. Индекс (merchant_id, created_at) в прямом запросе отрабатывает обе колонки и достаёт 469 строк. А через view условие приходит в виде CAST(created_at AS DATE) >= '2026-06-01' — это выражение, а не колонка, и границей диапазона по индексу оно быть не может. Остаётся условие по продавцу: все десять тысяч его заказов за 21 месяц вытаскиваются из кучи по разбросанным страницам, и уже там 9531 строка выбрасывается фильтром.

Итого 8971 обращение к буферам против 440 у прямого запроса.

MySQL на том же месте затрачивает 4.85 мс против 2.16 мс — в два с небольшим раза, а не в тринадцать. Механизм тот же, агрегирующая view в MySQL всегда TEMPTABLE (наличие GROUP BY запрещает MERGE), а условия внутрь проталкивает derived condition pushdown. Спасает MySQL то, что CAST он вычисляет прямо в индексе, index condition pushdown, строки‑кандидаты не поднимаются из таблицы вообще, отсекаются на уровне индексных записей.

Подзапрос с тем же текстом дал 26.9 мс, CTE — 24.6 мс. Так что дело не CREATE VIEW, а в семантике, любая конструкция с той же группировкой ведёт себя одинаково.

Проблема агрегирующей view не в том, что она «считает раньше, чем фильтрует». Проблема в том, что наружу она выставляет day, а индекс живёт на created_at. View честно отдаёт колонку, по которой невозможно попасть в индекс, и, делает это «молча», потому что интерфейс представления выглядит как интерфейс таблицы.

С тех пор при виде CREATE VIEW ... GROUP BY в pull request приходиться уточнять, какие колонки в неё выставлены наружу и есть ли под ними индексы. В восьми случаях из десяти этого хватает.

Каскад, который оказался быстрее прямого запроса

Три уровня: дневной агрегат, сумма поверх него, join со справочником наверху. Каждый уровень пересчитывается при каждом обращении. Ожидаем очевидное, чем глубже стопка, тем хуже.

PostgreSQL ожидание подтвердил, 832 мс против 243 мс у однопроходного запроса.

MySQL его опроверг, каскад 1436 мс против 2432 мс у прямого запроса. Стопка из трёх view оказалась почти вдвое быстрее однопроходного запроса, написанного руками.

Причина — форма join. Прямой запрос соединяет orders со справочником до группировки, с вложенным циклом: loops=750000 точечных обращений по первичному ключу. В каскаде join уезжает на самый верх, где после двух агрегаций от 750 тысяч строк остаётся 75. Воронка 750000 → 48000 → 75 видна в плане целиком.

У PostgreSQL в том же каскаде нашлось другое. Прямой запрос он выполняет в два параллельных воркера с одним HashAggregate. Каскад параллелизм теряет, а промежуточные 48 тысяч групп не влезают в work_mem 4 МБ:

HashAggregate (rows=48000) Planned Partitions: 32 Batches: 33 Memory Usage: 8209kB Disk Usage: 30224kB

Это 30 МБ на диск за одно выполнение. За серию из девяти прогонов счётчик temp_bytes в pg_stat_database вырос на 278 МБ, при том, что запрос возвращает десять строк. На десяти миллионах тот же каскад выливает уже 245 МБ, держа в оперативке 8,3 МБ, — PostgreSQL растёт не по памяти, а по диску.

Дорогой ли каскад — вопрос не глубины, а плана соединения и настроек памяти: поменяйте work_mem, и цифры поедут. План каскада нечитаем. Два вложенных Materialize → Aggregate using temporary table в MySQL, тридцать пять строк вывода в PostgreSQL, и всё это ради десяти строк отчёта. Когда такой отчёт затормозит в проде в четверг вечером, искать, на каком из уровней потерялось время, придётся глазами. Заранее предсказать, поможет каскад или обрушит систему, не выйдет — только проверять. И проверять на боевых объёмах, на тестовой базе планировщик покажет совсем другую картину.

ORDER BY внутри view

Классика кодовой базы: CREATE VIEW ... ORDER BY created_at DESC, “чтобы точно было отсортировано”. LIMIT 10 поверх такой view обе СУБД отдают мгновенно, сотые доли миллисекунды, обе читают индекс задом наперёд и берут десять записей. С фильтром сверху PostgreSQL справляется за 0.17 мс, MySQL — за 4.18 мс, и в обоих планах сортировки нет вообще, индекс уже даёт нужный порядок.

Цифры тут неинтересные. Интересна семантика, стандарт SQL не гарантирует порядок строк, которые отдаёт view, и документация MySQL говорит это прямым текстом. Сегодня план сложился удачно и данные выглядят отсортированными. Завтра оптимизатор пересчитает статистику, выберет другой доступ, и код, молча полагавшийся на порядок, начнёт отдавать «случайную» десятку. Такой баг не падает, не логируется и обнаруживается по жалобе пользователя через полгода.

Материализованные view и вопрос про кеш

Нативные материализованные view есть только в PostgreSQL. Чтение из mv_merchant_daily с уникальным индексом показывают 0.24 мс против 24.5 мс у живого агрегата, то есть в сто раз быстрее.

Цена на другой стороне. REFRESH на миллионе заказов занимает 1146 мс, и он всегда полный, инкрементального обновления в PostgreSQL нет. После вставок, задевших несколько сотен строк, REFRESH занял те же 1200 мс — дельта не влияет ни на что. Пишется он на диск ровно так же, как каскад, те же ~30 МБ временных файлов за выполнение.

Стократную разницу легко списать на кеш — «движок запомнил ответ». Но кеша результатов не существует ни в одной из двух СУБД. MySQL убрал Query Cache в 8.0, в PostgreSQL его никогда не было, кешируются только страницы данных.

Проверка простая, тридцать повторов одного запроса через агрегирующую view подряд. Медиана MySQL 4.37 мс при максимуме 5.95, PostgreSQL 21.7 мс при максимуме 25.2. «Плоская» серия, каждый прогон считает заново.

Счётчики говорят то же самое иначе. В PostgreSQL тяжёлый агрегат обслуживается целиком из прогретого пула 9456 попаданий, ноль обращений к диску, 23 мс. Чтение материализованной view это сотня попаданий, 0.24 мс. Оба запроса читают одинаково прогретые страницы и различаются в сто раз, разница чисто вычислительная. У MySQL картина в терминах InnoDB, за прогон ноль физических чтений, 5883 логических из буферного пула и Created_tmp_tables +7, временные таблицы рождаются и умирают вместе с каждым выполнением.

Материализованная view быстрее не потому, что «кешируется», а потому, что вычислять уже нечего.

Что чтение view делает с записью

Пятнадцатисекундные окна вставок пачками по восемьсот строк. Базовая линия — только вставки. Второй сценарий добавляет двух фоновых читателей, непрерывно гоняющих агрегирующую view.

Скорость записи просела на 7% в MySQL и на 16% в PostgreSQL. Читатели при этом получали около семидесяти запросов в секунду с медианой 7 мс.

Контрольный сценарий заменил живую view сводной таблицей, которую писатель поддерживает инкрементальным upsert’ом по затронутым группам. Вставки не просели вообще: 24 000 строк против 22 400 у базовой линии в MySQL, 20 800 против 20 000 в PostgreSQL — плюс 7% и плюс 4%, то есть чистый шум фоновой нагрузки хоста. Консистентность снапшота сверил отдельно.

Сама по себе view записи не мешает. Мешает постоянный читатель тяжёлого агрегата, он делит ресурсы с писателем и за каждое своё чтение расплачивается полным пересчётом. Поддержка сводной таблицы на стороне писателя не стоит ничего.

Цена зависит не от запроса, а от объёма

Те же сценарии на десяти тысячах заказов, потом на миллионе, потом на десяти миллионах.

Заказов

MySQL, view/direct

PostgreSQL, view/direct

10 000

1.6×

2.7×

1 000 000

2.3×

10.7×

10 000 000

2.5×

50.4×

MySQL держится ровно на всём диапазоне, index condition pushdown работает при любом объёме, лишние строки отсекаются в индексе. А у PostgreSQL отставание растёт вместе с данными.

Механически это тот же CAST, view всегда читает все заказы продавца, а прямой запрос — только заказы за июнь. При окне данных это ровно 21-кратная разница во входе, и она не зависит от объёма. А измеренный разрыв растёт с 2.7× до 50×, то есть обгоняет её вдвое с лишним. Планов на десяти миллионах я не снимал, поэтому объяснения у меня нет, есть гипотеза — сто тысяч случайных обращений в кучу перестают попадать в прогретый пул, и к вычислениям добавляется реальный ввод‑вывод.

Проверять это я не стал: на решение, которое из этого следует, ответ уже не влияет.

Потому что рядом стоит третья стратегия.

Чтение из сводной таблицы, которую поддерживает пишущая сторона, не зависит от объёма вообще: 0.02–0.20 мс и на десяти тысячах, и на десяти миллионах. На верхней границе это в 1470 раз быстрее живой view в MySQL и в 4847 раз — в PostgreSQL.

Поддержка таблицы не бесплатна, полный пересчёт на десяти миллионах занимает 19 секунд в MySQL и 7 секунд в PostgreSQL. Для свежести «раз в сутки» это ничего не значит, подходит любой вариант, хоть REFRESH, хоть rebuild. Для свежести «каждую секунду» материализованная view выбывает уже на миллионе, один REFRESH длится дольше интервала между ними.

До десятков тысяч строк выбор между живой view и сводной таблицей, вопрос вкуса, и спорить о нём глупо. Ближе к миллиону это становится вопросом архитектуры, а за миллионом выбора уже нет.

Сколько это в мегабайтах

Претензия к представлениям, которую я слышал чаще прочих, звучит как «они жрут ресурсы». Время я померил, а память нет, и это был пропуск в рассуждении, агрегирующая view создаёт временную таблицу, а временная таблица где‑то живёт.

Считал рабочую память запроса, а не буферный пул, тот выделен заранее и от способа чтения не зависит совсем. В MySQL это прирост памяти треда соединения из performance_schema, в PostgreSQL память узлов плана из EXPLAIN (ANALYZE, MEMORY) плюс то, что ушло на диск.

Простая view не стоит ничего и здесь. 75 КБ против 33 КБ у прямого запроса на миллионе, разница — накладные на разбор определения, и с объёмом она не растёт. В PostgreSQL в плане нет ни одного рабочего узла, считать нечего.

Агрегирующая view в MySQL стоит ровно мегабайт. Не «мегабайт на миллионе и десять на десяти миллионах», а мегабайт всегда, пока проталкивается предикат. Если не проталкивается, в таблицу ложится весь результат view, выключил проталкивание хинтом на том же запросе, и, 15 535 КБ вместо 1262, 12,8 секунды вместо 59 миллисекунд. Это блок аллокатора TempTable, он выделяется целиком под любую временную таблицу, хоть на тридцать строк результата. Прямой агрегат тратит те же 1082–1181 КБ.

Дальше пошло то, чего я не ждал. Каскад из трёх view — 13 706 КБ на миллионе и те же 13 706 КБ на десяти миллионах. Я решил, что сломался замер, и полез проверять. Замер не сломался, память группировки определяется числом групп, а не числом строк. Комбинаций «продавец × день» в моих данных 48 000, семьдесят пять продавцов на 640 дней, и это потолок, который не двигается, сколько заказов ни залей.

Рекорд серии поставил запрос вообще без единой view. Тот самый однопроходный отчёт, который в MySQL оказался вдвое медленнее каскада, на десяти миллионах занял 526 МБ и единственный во всей серии свалился во временную таблицу на диске, он соединяет заказы со справочником до группировки, и семь с половиной миллионов строк материализуются целиком. Каскад на тех же данных — 13,7 МБ, в тридцать девять раз меньше.

Чтение из сводной таблицы — 24 КБ на любом объёме и ноль временных таблиц. Готовому снапшоту нечего вычислять, значит, и держать в памяти нечего.

Разница между стратегиями проходит по времени и по спиллу на диск, а не по мегабайтам.

Симптомы проблем с VIEW

Если тяжёлая view уже живёт у вас в проде, выглядит это так, процессор и временные объекты растут без внятной причины, а отчёты деградируют не плавно, а ступенькой. Смотреть — Created_tmp_tables и Created_tmp_disk_tables в MySQL, temp_bytes в pg_stat_database у PostgreSQL. Дальше EXPLAIN ANALYZE по подозреваемому и поиск view в «горячем» пути через performance_schema или pg_stat_statements.

Итог

  • Простая view действительно не потребляет ресурсы, оба движка смотрят сквозь неё.

  • Без MERGE, TEMPTABLE и правил перезаписи не объяснить ни тринадцатикратную разницу на агрегате, ни пятидесятикратную на масштабе.

  • В MySQL каскадные view могут рассматриваться, как элемент оптимизации.

  • Агрегирующая view в «горячем» пути, плохой подход, её стоимость растёт быстрее данных, а у PostgreSQL растёт кратно.

  • ORDER BY внутри view порождает тихие баги вместо удобства.

  • Материализованная view окупается только там, где чтений сильно больше записей и лаг данных никого не расстраивает.

  • Сводная таблица с инкрементальной поддержкой дешевле на порядки и от объёма не зависит, поэтому агрегаты у меня часто живут отдельными таблицами.

  • Потребление ресурсов агрегирующей view в колонках, которые выставляются наружу. Индекс лежит на соседней колонке, и дотянуться до него из запроса уже нельзя. Формулировка звучит мельче, а на практике решает больше, она подсказывает, что чинить.

  • По потребляемой памяти view в современных движках всё хорошо и не вызывает особого беспокойства, как раньше.

Где view полезно применять:

  • переиспользуемый фильтр и стабильный контракт чтения;

  • разделение прав — с оговорками про security_invoker и security_barrier в PostgreSQL, SQL SECURITY в MySQL;

  • мягкая миграция, когда старое приложение читает старый интерфейс поверх новой схемы;

  • legacy, который проще обернуть, чем переписать;

  • дашборды на материализованной view при редкой записи.

Список ниш, который я назвал на том собеседовании, не изменился ни на пункт. Изменилось другое, за каждым пунктом теперь стоит план запроса, а не привычка.

Автор: Александр Фролов · Senior/Staff Backend Engineer · PHP Highload · Symfony · Architecture · Team Lead · Стенд: github.com/alex‑frolov/mysql‑postgresql‑view‑test

Комментарии (86)


  1. K2_Chicago
    26.08.2026 00:37

    По моему опыту с Oracle, view как элемент разработки (developer's views) встречается действительно очень редко и польза невелика.
    Польза от объекта view всё же есть:
    1. Materialized view. Запрос, который выполняется долго, результат меняется мало - такой объект обновляют, скажем, один раз в сутки ночью при малой нагрузке, а клиенты используют днем и часто.
    2. Ну и разумеется системные view, когда не дают доступа к исходным таблицам.

    Может быть, view вообще были созданы исторически, на заре первых реляционных баз, и они были тогда гораздо более полезными?

    По-моему, такое встречается, в разных языках живут реликты до-PCшной эпохи или эпохи процессоров 286.
    Например, R - очень хороший язык, но эта "реактивность" по-моему там и нафиг на далась, только усложняет и изучение и отладку. Когда читаешь про зачем и почему реактивность в R -сплошь и рядом одно и то же маловразумительное объяснение мол это делает работу быстрой.
    Да, делало наверное лет 20 назад, а сейчас и без реактивности быстро.
    извините, приведу цитату из моего любимого МихалЕвграфыча -
    "вы считаете, следует ли ссылать литераторов в Сибирь по суду или без суда?
    - я, ваши превосходительства, раньше думал что лучше жарить их в Сибирь по суду - крепче будет. А теперь вижу - крепко и без суда!
    "


    1. Politura
      26.08.2026 00:37

      Может быть, view вообще были созданы исторически, на заре первых реляционных баз, и они были тогда гораздо более полезными?

      Раньше в базе частенько держали бизнес-логику, или хотябы часть ее, тогда и все эти вьюхи, хранимки и даже разграничение доступа использовались намного чаще. Например, в нулевых я видел приложения у которых вообще не было своего управления юзерами, весь контроль, включая rbac был на стороне базы, пользователь вводил логин/пароль, приложение пыталось логиниться в базу с этими введенными данными и пользователь имел тот доступ в системе, который был разграничен для его роли в базе. Вьюхи там использовались вовсю, и напрямую к таблицам доступа ни у кого не было.

      Теперь общепринятая практика - вся бизнес-логика на стороне сервера приложений, а база тупо хранилище. Вот и не нужны вьюхи больше. Как и хранимки, rbac и прочее.


      1. K2_Chicago
        26.08.2026 00:37

        Теперь общепринятая практика - вся бизнес-логика на стороне сервера приложений, а база тупо хранилище

        Как всегда, обобщение на основе собственного ограниченного опыта.

        Очень даже хранят бизнес-логику в stored procedures/functions. И в Oracle, и в Postgres.
        "База тупо хранилище" ну может быть в data warehouse приложениях. Работаю 20 лет в Штатах, ни разу не сталкивался с "тупо хранилище". Бизнес логика была на сервере приложений, да, когда работали на формсах. Еще была в шелл-скриптах в фирме которая выпускает автомобильные каталоги. Сейчас вся логика в "хранимках" в фирме которая держит глобальный архив научных публикаций.

        Но вьюхи к бизнес-логике опять же непосредственного отношения не имеют.
        Курсоры наше все для сложных запросов.


        1. Politura
          26.08.2026 00:37

          Но вьюхи к бизнес-логике опять же непосредственного отношения не имеют.

          Если хочется, то имеют, например пользователь должен видеть только данные своего департмента, вот ему доступ к вьюхам, где данные отфильтрованы по департаменту, а к оригинальным таблицам у него доступа нет.

          Про обобщение даже спорить не хочу. Популяризация ОРМ, микросервисов, горизонтального масштабирования, database-agnostic подхода, да банально юнит-тестирования, все это вытесняло бизнес-логику из баз данных.


          1. K2_Chicago
            26.08.2026 00:37

            Вы знаете, вы задели занятную тему. Вот эти вот buzz-words " ОРМ, микросервисы, горизонтальное масштабирование, database-agnostic подход". Здесь на хабре эти словечки кишмя кишмят, (ну и плюс про интервью, джунов, сениоров, выгорание, бла-бла) и даже возникает впечатление у многих что вот она, реальная кипучая буча.
            А я по жизни вижу что это все вообще к жизни IT отделов в больших фирмах (звиняйте, в маленьких работать не доводилось) - вообще никакого отношения не имеет. В жизни все как 15-20 лет назад, все по-простому, по-старинке. И весь IT-народ в годах от 40 до 70. И никаких новых серьезных DB-приложений никто не разрабатывает, везде только поддержка или миграция. И кстати, я вижу как высокое руководство тоже заражается всеми этими агентами, ИИ, нам все время спускают какие-то емейлы про семинары, курсы про ИИ, про обсуждения политики...но этот весь хайп он где-то там, он разработчиков вообще не касается, никому это в девеломпенте не нужно, пропускаем все мимо ушей и емейлы автоматом в трэш. И здесь вот на хабре какой-то безумный хайп, а жизнь-то...она проходит рядом и параллельно и этот хайп в ней как те сократовские тени на стене пещеры. Помните в фильме про Молчаливого Боба - "вот это пульс, вот это - палец, и он далеко от пульса!". Вот это - жизнь IT отдела, вот это - бурные дискуссии на хабре, и они далеки от жизни!"
            Моё IMHO, спорить не стану.

            ЗЫ примерчик из жизни и болтовни: во всех емейлах мол, think out of the box, innovation, frontiers...меня попросили сделать простой фронт-енд для простейшего DB-приложения, 5 табличек, исключительно для внутреннего пользования, на десяток юзеров максимум. Сделать "на чём-нибудь на ваше усмотрение". Я оканчивал пажеский корпус (биофак МГУ) и ваших веб-фреймворков не обучен, пошарился в сети и слепил миленький фронт-енд..на R, там есть библиотечка Shiny, все ГУИ-виджеты, готовые гриды, только распихать по клеткам на странице. Маленькая программа получилась, всего два текстовых файла, закидываешь по FTP на амазоновский микро-образ люникса и все летает. Сделал, продеплоил, презентовал, молчат. Потом главный менеджер IT - мол, это сложно, так никто не делает и у нас нет ресурсов которые будут поддерживать программу на таком странном языке. Через пол-года дали нам супер-пупер питониста, он уже почти год лепит нам чудище обло на Flask, там у него все самое модное - и Docker, и Jenkins, сам чёрт ногу сломит. Причем он временный, слепит это самое, уйдет и что - из наших айтишников никто и питона-то не знает, а уж Flask тем более, и Docker, Jenkins - вообще китайский язык.
            Думайте, говорят, out of the box. Инновации, говорят. Учите новое, расширяйте квалификацию, говорят.

            П<>болы, везде п<>болы.


            1. panzerfaust
              26.08.2026 00:37

              Вы знаете, вы задели занятную тему. Вот эти вот buzz-words

              ...

              Причем он временный, слепит это самое, уйдет и что - из наших айтишников никто и питона-то не знает, а Docker, Jenkins - вообще китайский язык.

              Докер уж лет 10 как продакшн-реди, лет 6 как стандарт де-факто. Дженкинсу в этом году 15 лет. Когда работал с ним 7 лет назад, то он уже казался лютым олдскулом. При этом нишевый язык R для вас норм. А я о нём знаю только в контексте биотеха, например.

              В целом-то совет думать out of the box не такой и дурной.


              1. K2_Chicago
                26.08.2026 00:37

                Я лично ненавижу слово "стандарт" в обсуждении разработки. Прям кюшать не могу. ВСЕГДА это вот "у нас есть стандарт" используется как "аргумент" для оправдания бессмысленных, неправильных и волюнтаристских практик к которым принуждают разработчика. "У нас agile стандарт"! "У нас docker стандарт" и прочий бред, простите мне мой клатчский.
                Муму-папа говорил: "не то хорошо, что хорошо, а что к чему идет".
                Подумайте об этом, Муми-папа плохого не скажет.

                Но вы я вижу даже не поняли что "совет думать out of the box" - это пример корпоративного лицемерия и демагогии. Судя по тому, что для вас язык R - "нишевый" ...да что там.


                1. panzerfaust
                  26.08.2026 00:37

                  Я лично ненавижу слово "стандарт" в обсуждении разработки

                  А я вот грешен. Люблю стандарты. Везде. Мне очень нравится, что USB 3.0 в Китае и во Франции это одно и то же. Или болт M6x20 в Индонезии не отличается от такого же болта в Финляндии. И в разработке тоже классно, что приходишь на новый проект и начинаешь сразу работать, а не изучать местные велосипеды.

                  Судя по тому, что для вас язык R - "нишевый" ...да что там.

                  Судя по тому, что для вас докер баззворд...


                  1. K2_Chicago
                    26.08.2026 00:37

                    И вас не смущает ситуация когда менеджер IT комады из 4х человек на возражение нового разработчика что нельзя хардкодить мастер-пароль в коде приложения заявляет: у нашей команды есть стандарты и мы их не обсуждаем. Я вот про эти "стандарты". Любое ничтожество на ступень выше корзинки для бумаг использует "стандарты" чтобы затыкать "сильно умных".


                    1. VladimirFarshatov
                      26.08.2026 00:37

                      мастер пароль в хардкод мелочи. Хуже когда вместо сборки бизнес-логики в один кучерявый цикл, слышишь что у нас стандарт и 1 действие на завернуть в одну функцию и .. требование размазать коммит по функциям с циклом внутри. Производительность падает /N но в ответ слышишь "у нас крутой сервер, а стандарт нарушать нельзя, если заткнется попросим руководство купить новую стойку".


                  1. VladimirFarshatov
                    26.08.2026 00:37

                    Не передергивайте. Стандарт в железе это не просто хорошо, а придумано давным давно. ГОСТом зовется. А вот "стандарт в программировании" это совсем иное. Ещё худо-бедно можно принять некий "стандарт" в девопсе, ну .. "не ругайте пианиста от играет как умеет", а вот "стандарт" в бизнес-логике - это дурь, полностью соглашусь с вашим оппонентом.


                    1. panzerfaust
                      26.08.2026 00:37

                      Передергиваю тут не я. Мой тезис был про том, что докер есть стандарт де-факто и уж точно не баззворд в 2026 году. Где докер и где бизнес-логика? Мне на это отвечают что-то про ненависть к стандартам, волюнтаризм, какого-то менеджера, какой-то хардкод. Про Фому и про Ерёму, как говорится.


                      1. Okeu
                        26.08.2026 00:37

                        разраб сидит в тумане войны, и лепит то, что ему хочется и по кайфу, а не то, что нужно бизнесу и за что бизнес деньги готов платить. Единственное, что бизнес не в курсе такого положняка, пока что)


                      1. SHLab
                        26.08.2026 00:37

                        Был в курсе, но это время прошло


                    1. Okeu
                      26.08.2026 00:37

                      стандарты разные бывают, и в бизнес логике тоже. Другой вопрос - называть стандартами то, что ими не является - это дурь. Но стандарты есть во всем - и вы их используете, просто можете даже не догадываться об этом.


                1. Rive
                  26.08.2026 00:37

                  "Стандарт" означает, что им не придётся ломать голову над требованиями к вакансии человека, которого они наймут поддерживать это приложение.


                1. Fromych
                  26.08.2026 00:37

                  Звучит как крик души человека, которому бездушный CI/CD завернул пулл-реквест из-за неправильных отступов)

                  Стандарт нужен просто для того, чтобы новый разраб вкатился в проект за неделю, а не реверс-инжинирил твои уникальные паттерны полгода


                  1. oleg_go
                    26.08.2026 00:37

                    Стандарт нужен для того чтобы при наличии 10 проектов и 5 разрабов переключение их между проектами было легко и непринужденно. Когда во всех проектах всё находится по стандартным местам, называется тоже стандартизованно и выполняет атомарные операции, то любого разработчика можно привлечь на любой проект. Для бизнеса очень плохо когда все как хотят так и пишут. Разрабы узкоспециализированы по проектам и свои компетенции и знания кодовой базы держать в тайне в своей голове. Почему кирпичи делают прямо и перпендикулярно и более менее одинакового размера - чтобы когда строится дом не нужно было каждый раз решать а что в этот кирпич хотел вложить его создатель.


            1. DarthVictor
              26.08.2026 00:37

              А я по жизни вижу что это все вообще к жизни IT отделов в больших фирмах (звиняйте, в маленьких работать не доводилось) - вообще никакого отношения не имеет.

              А IT отделы в фирмах, доходы которых напрямую не зависят от их програмных (ну либо програмно-аппаратных) продуктов, в целом мало отношения имеют к тому, что понимают под IT.


              1. K2_Chicago
                26.08.2026 00:37

                т.е. IT-отдел, скажем, в Газпроме или Сбере - это не IT, так, шарага
                А вот IT-отдел, например, в Люксофте - это ого-го.
                Очаровательно.


                1. ManulVRN
                  26.08.2026 00:37

                  ИТ-отдел в Сбере, иначе известный как Сбертех это, в каком-то смысле, и есть Сбер сегодня, у Сбера ИТ сейчас (да и практически у любого банка) - основа деятельности. Про Газпром не знаю.


                1. UFO_01
                  26.08.2026 00:37

                  Не совсем корректные примеры, у сбера ИТ направление развито и является основой деятельности, как и у любого другого банка - экосистема, все дела. Газпром отдельный прикол, с их-то количеством дочерних компаний. Но вот скажем ИТ отдел на каком-нибудь заводе (если не брать мастодонтов) и ИТ отдел сбера это разные вещи.


            1. ManulVRN
              26.08.2026 00:37

              Ну это такого суперспеца вам дали, если он полгода лепит фронт к 5 табличкам.

              Я работал на заре карьеры в компании, которая не имела никакого отношения к ИТ и мы были прислугой (хотя относились к нам хорошо). Очень типичная картина, кто на чем привык - на том и пишет, лет по 10-15 на одном и том же, что-то новое попробовать - пожалуйста, если у тебя зудит, делай что хочешь. Если не хочешь - не пробуй, у нас проверенного FoxPro (олды знают) сколько угодно. Но это не типичная для ИТ-отрасли картина.


              1. K2_Chicago
                26.08.2026 00:37

                вы делаете вывод что он плохой специалист?

                ну, вы рассуждаете не лучше.
                Он явно знающий спец, но у него нет мотивации и он по сути работает 15 минут раз в неделю, как раз перед нашим еженедельным созвоном в MS Teams.


              1. UFO_01
                26.08.2026 00:37

                Какого суперспеца не посади, если он бесконтрольно работает на почасовке или без сроков, он когда-нибудь потом будет вашими проблемами заниматься.

                Кстати, как мне кажется, если что-то пишется в рамках деятельности компании, всегда есть типовой интсрументарий. Если же решили делать что-то нетипичное, там в первый раз делается кто во что горазд. А потом уже делают с оглядкой на этот опыт.

                Отдельный прикол кстати когда все используют комбайн, но по-разному. Вот с qt всегда прикольно. Один использует чистые QWidget, другой QWidget + QSS, третий сидит на формочках, четвёртый на QML. Отдельные уникумы вообще переопределяют paintEvent или QGraphicsView, добавляют биндинги на другие языки или используют WebEngine.


            1. sherbinko
              26.08.2026 00:37

              20 лет назад мобилки были так себе. Щас любой веб-сайт должен уметь работать во всех девайсах и браузерах. Непонятно как только с помощью "поддержки" сие осуществить.
              Я работал во многих конторах и вподавляющем большинстве там были и докеры и дженкинсы. Ваш случай нерепрезентативен.
              Но вообще пост похож на какой-то троллинг если честно


            1. UFO_01
              26.08.2026 00:37

              Насколько мне видится, написать фронт на нишевом R это как раз-таки out of the box решение. А вот использовать стандартные инструменты это как раз-таки правильный путь. Думать out of the box нужно только в том случае если in the box решение нас не устраивает.

              Приведу пример. Я вообще c/c++ разработчик, иногда пишу на питоне, иногда использую матлаб. И вот как-то надо было накалякать приложение на Android. Что я сделал? Правильно, взял стандартный вариант - kotlin + jetpack compose. Единственная вольность которую себе позволил - для работы с serial написал свою реализацию на kotlin.

              Дело не том, инновация или нет, баззворд или нет. Дело в целесообразности. Если достаточно запилить монолит, не вопрос, делаем. Если мы прикинули и поняли что монолит не подойдёт, окей, микросервисы. Если нам норм держать логику в базе, окей, нет - выносим логику, если надо ОРМ используем. Достаточно наколеночного решения, хозяин барин.

              А по поводу питониста

              Анекдот

              Молодой адвокат прибегает к своему отцу — старому адвокату и радостно говорит: "Отец! Я выиграл дело, которое ты вел 20 лет!". Отец ему отвечает: "Дурак ты, сынок! Благодаря этому делу я вас 20 лет кормил..."


          1. oracle_schwerpunkte
            26.08.2026 00:37

            Не, тут по другому - единственная система на которой имеет смысл иметь бизнес логику в базе - это Oracle. Там все сделано для людей. Даже очень похожий постгрес уже гораздо менее удобен.


        1. Cordekk
          26.08.2026 00:37

          Указали, что "теперь общепринятая практика" для новой разработки, поддержка того, что программировалось 10-20 лет назад - это как всегда другая история.
          Молодые программисты в большинстве своем в SQL не лезут вообще, пользуются ORM.


      1. Spiritschaser
        26.08.2026 00:37

        Немного не так. Как в статье написано, materialized view обновляется в постгресе без инкремента, поэтому следующим шагом будет создание таблицы с инкрементным обновлением хранимкой по расписанию в pg_cron, а view исчезнет.


        1. VladimirFarshatov
          26.08.2026 00:37

          Многие конторы и их рахработчики (по крайней мере лет 5 назад) были яростно против хранимок вообще как факта. Не в курсе как сию, отошел от скуля.


          1. Spiritschaser
            26.08.2026 00:37

            Да я сам всё перетянул в даги airflow - просто чтобы всё на виду было. Это вопрос организационной, а не технической сложности.


            1. ln123
              26.08.2026 00:37

              А можите написать подбробнее в чем получилось удобство дагов перед хранимками. На мой взгляд если смотреть со стороны базы то как раз наоборот получается хранимки они вот под рукой рядом с данными все зависимости видны, а даги они где-то сбоку...


              1. Spiritschaser
                26.08.2026 00:37

                А тут всё просто: airflow всё равно нужен для разного, + у airflow отличный мониторинг результатов выполнения. А в pg_cron своё городить... Ну и если я уйду, любой инженер разберётся - не надо документировать ещё и служебные таблицы и хранимки


      1. micronull
        26.08.2026 00:37

        Раньше в базе частенько держали бизнес-логик

        Был опыт работы в одной команде, которой надо было пилить свои фичи взаимодействуя с проприетарным ПО, у которого отсутствовало API, но были свои хранимки в БД. Вот через них мы и делали интеграцию.

        Отладкой было не приятно заниматься.

        Самый сок происходил после обновления софта.


      1. Fromych
        26.08.2026 00:37

        Теперь общепринятая практика - вся бизнес-логика на стороне сервера приложений, а база тупо хранилище. Вот и не нужны вьюхи больше. Как и хранимки, rbac и прочее.

        Это правило работает только для типичных крудов и микросервисов на полтора эндпоинта. Загляни в любой живой корпоративный DWH, там этих вьюх столько, что без поллитры не разберешься


    1. Z55
      26.08.2026 00:37

      По моему опыту с Oracle, view как элемент разработки (developer's views) встречается действительно очень редко и польза невелика.

      Сам Оракл с вами не согласится, ибо вспоминаем про встроенные вьюхи user/dba/all_*


      1. K2_Chicago
        26.08.2026 00:37

        Сам Великий и Ужасный Оракл - имеет главной мотивацией не развитие технологии и удобство разработчиков и пользователей, а новые яхты Ларри. Тоже мне авторитет. Был, да весь вышел. Формсы убили, JDeveloper не взлетел, APEX у них теперь "приложение", а ведь задумывался то как HTML DB.


        1. Z55
          26.08.2026 00:37

          Сам Великий и Ужасный Оракл - имеет главной мотивацией не развитие технологии и удобство разработчиков и пользователей, а новые яхты Ларри.

          Это можно сказать про любую коммерческую компанию

          JDeveloper не взлетел

          Ну он откровенно был убог, особенно в сравнении с PL/SQL Developer и Toad. Плюс ещё и бесплатный продукт, которых жрёт бюджет. Поэтому на него в 2013м положили огромный болт. Не может же Ларри несколько лет подряд ходить на одной и той же яхте?


          1. K2_Chicago
            26.08.2026 00:37

            Как это вы сравниваете оракловский JDeveloper с TOAD???
            JDeveloper это монструозный фреймворк для front-end разработки, а TOAD - это просто утилита для SQL (и PL/SQL).


            1. Z55
              26.08.2026 00:37

              Сравниваю с позиции dba этого самого оракла. И в этом плане, он более чем ужасен.


      1. K2_Chicago
        26.08.2026 00:37

        а я уже писал что не отрицаю пользу материализованых и системных вьюх. Вы не читали?


    1. m03r
      26.08.2026 00:37

      Если в R под реактивностью имеются в виду ленивые вычисления, то польза от них очевидна: без них не работало бы nonstandard evaluation, на котором основаны dplyr, data.table и многое другое. Всё это работает так удобно благодаря тому, что аргументы функции не вычисляют сразу, и с ними можно работать, как с выражениями


      1. K2_Chicago
        26.08.2026 00:37

        в R "под реактивностью" понимаются reactiveVal(), reactiveValues(), reactive(),observeEvent(), isolate() и пр. и пр. и пр.


        1. m03r
          26.08.2026 00:37

          Это же запчасти Shiny. Для интерактивных штук реактивность в целом максимально полезна (не пересчитывать то, что пересчитывать не нужно)


  1. DarKsandr
    26.08.2026 00:37

    На своей практике встречал подмена данных через view. Сначала у нас есть старая таблица с данными и view на нее, потом мы создаём вторую таблицу и после ее заполнения меняем view уже на нее, тем самым получаем новые данные без задержки в подмене


    1. FrolovAlexander Автор
      26.08.2026 00:37

      Классический паттерн blue-green через view. Работает отлично для миграций схемы.


  1. redfox0
    26.08.2026 00:37

    С одной стороны сложно согласиться с ненужностью представлений (view). В проектах с ORM действительно нет view, либо их единицы.

    С другой стороны применение view довольно простое: для ограничения доступа (создали view, добавили фильтр и выдали права пользователю, можно даже менять данные в колонках); хранение запросов, чтобы не дублировать код в десятках местах; просто спрятать большой запрос во view (например, гигантский merge с сотней колонок, часть с select уходит во view).

    Современные СУБД довольно сильно оптимизируются запросы, так что проблема производительности обычно не стоит, стоит выдача гранулярных прав доступа и поддержка кода: https://javarush.com/groups/posts/423-kljevihe-optimizacii-sql-ne-zavisjajshie-ot-stoimostnoy-modeli-chastjh-5-


    1. Cordekk
      26.08.2026 00:37

      именно это автор и написал в начале.


  1. denisemenov
    26.08.2026 00:37

    Небольшой оффтоа. А вы клодом писали эту статью или кем, если не секрет? Просто он так качественно выдаёт тексты в таких формулировках, которые кажутся умными, но понять этот текст намного сложнее, чем тут написанный человеком или даже кодексом. Если вообще он имеет смысл, потому что я устал бороться с клодом на тему его некомпетентности, вранья и скрытия косяков. И его стиль мне узнается теперь часто. Судя по негативу в зарубежных соцсетях, я уже не один такой параноик.


    1. panzerfaust
      26.08.2026 00:37

      ИИшка тут точно потопталась. Очень знакомый паттерн, когда в тебя как будто выстрелили картечью из терминов вперемешку с обычными словами в пропорции 1:1. Читаешь, читаешь, потом мысль "А что сказать-то хотел?".


    1. FrolovAlexander Автор
      26.08.2026 00:37

      Текст написан мною вручную. Все замеры берутся со стенда github.com/alex-frolov/mysql-postgresql-view-test, и запускается одной командой. Если есть конкретные технические вопросы по цифрам или планам - с удовольствием разберу.


      1. denisemenov
        26.08.2026 00:37

        Не понимаю, зачем так рьяно пытаться опровергать очевидное - ИИ виден невооружённым глазом по тонне клише, использованных как в тексте, так и в оформлении. Ну ок. Вручную так вручную. Удачи вам.


  1. tooshcan4ik
    26.08.2026 00:37

    А что на счёт клика? можно такой же замер с кликом?


    1. FrolovAlexander Автор
      26.08.2026 00:37

      Стенд открыт на github.com/alex-frolov/mysql-postgresql-view-test, там docker compose up && make bench. CLICK-подобные ворклоады прогоняются так же, дописываешь свой SQL в bench/queries.sql и запускаешь. Если соберёшь интересные цифры, присылай PR, с удовольствием приму, посмотрю. Можно и здесь обсудить.


  1. bigtrot
    26.08.2026 00:37

    View позволяют разделить физическое хранение данных от их использования. Через view создаем интерфейс доступа к данным.В процессе разработки и эксплуатации может меняться физическая схема, а view позволяют поддерживать неизменный интерфейс. Кроме того во view можно заложить сложный запрос, который пишут те люди, которые знают физическую схему базы данных, а прикладные программисты выдвигают требования в каком виде им требуются данные. По сути view позволяют создать "витрину данных" для прикладных задач. То же самое касается и функций. Так что функции и представления полезны и позволяют организовать технологию разработки и эксплуатации разделяя, степень ответственности и компетенции.


    1. K2_Chicago
      26.08.2026 00:37

      прямо слово-в-слово из рекламной брошюры 40-летней давности.


      1. frrrost
        26.08.2026 00:37

        шутки шутками, а у меня большой DWH с кучей команд в одной базе. И для разграничения доступа (и ответственности) все ходят друг к другу через вью-интерфейсы. Это действительно удобно и кучу раз нас выручало, когда схема за вью менялась


        1. iamkisly
          26.08.2026 00:37

          У нас это называется "витринами". Я последние лет пять только и делают что леплю вью для различных подразделений кампании.


          1. frrrost
            26.08.2026 00:37

            ну витрины - это обычно то, что отдается бизнес-пользователям. Перед витринами у нас тоже стоят вью в роли интерфейсов)


          1. FrolovAlexander Автор
            26.08.2026 00:37

            Согласен, в DWH, много-командных базах и при миграциях view, как контракт - интерфейса незаменимы. В статье это в итогах: "переиспользуемый фильтр и стабильный контракт чтения", "разделение прав", "мягкая миграция", "legacy, который проще обернуть". Мой кейс это OLTP highload, там агрегаты, часто дешевле выносить в сводные таблицы с инкрементальным обновлением.


      1. SHLab
        26.08.2026 00:37

        «Древние» знали толк в оптимизации. Их еще не развратили современными мощностями, которые покрывают нежелание программистов писать код оптимально )


    1. FrolovAlexander Автор
      26.08.2026 00:37

      Точно. В статье это "переиспользуемый фильтр и стабильный контракт чтения" + «"legacy, который проще обернуть". Для OLAP/DWH — основной паттерн.


  1. dmitryez
    26.08.2026 00:37

    Например юзер может быть удален, заморожен, заблокирован, а я хочу работать только с живыми юзерами. Создаем view и работаем только с этим view.

    create or replace view active_users as
    select * from users
    where status_id is null;

    Меньше рисков потерять условие, меньше сами запросы, меньше дублирования логики.


  1. oracle_schwerpunkte
    26.08.2026 00:37

    Разделение ответственности. VIEW - бизнес логика, TABLE - хранение.
    Сравните CREATE TABLE statement и CREATE VIEW.
    CREATE TABLE - это партиции, tablespaces, компрессия и прочие ДВА штучки.

    Для представления -

    1. Можно пересоздавать(REPLACE), очень удобно в скриптах

    2. поддерживаются EDITIONING, без версий тестирование - боль.

    3. WITH READ ONLY, WITH CHECK OPTION, BEQUEATH наконец.


  1. Plesser
    26.08.2026 00:37

    Я ответил честно: в живых проектах они мне почти не попадались; для агрегатов надёжнее держать отдельную таблицу; а сами представления — вещь настолько нишевая, что за карьеру пригождались считанные разы. Разделение прав, долгие миграции, совместимость со старым ПО — вот и весь список. Ответ приняли прохладно. 

    мне кажется я понимаю почему они приняли ответ прохладно

    Представления прежде всего нужны когда у тебя есть один сложный sql запрос, который используется во многих местах. Ты создаешь представление и используешь его. Когда тебе надо внести в него изменение, ты вносишь только в одном месте изменение, а не начинаешь судорожно искать где у тебя используется этот sql.


    1. iamkisly
      26.08.2026 00:37

      Я думаю все иначе. Подозреваю, что люди вроде автора работают через ORM. Когда ты перманентно находишься в application layer, то испытываешь.. проф искажение: не вижу, чтобы использовали в моей кампании - нигде не используют. На деле такие правила чаще всего существуют по присинам как в анекдоте "тут так заведено".


      1. Plesser
        26.08.2026 00:37

        как вариант кстати, да


  1. alan008
    26.08.2026 00:37

    Иногда требуются какие-нибудь хитрожопые SELECT'ы с фильтрами к результату соединения пары десятков таблиц. Писать такие соединения "каждый раз" напрягает. Проще завести VIEW (обычный, не материализованный), а потом к нему во WHERE добавлять только фильтры. Типа SELECT * FROM MyMegaView WHERE <динамически собираемый фильтр>


  1. oldDBA
    26.08.2026 00:37

    Тут нужно начать с CAST(o.created_at AS DATE) AS day и group by по ней же.

    Вот я, как DBA, дал бы разрабу по башке. Потому что это азы SQL. Да, можно достроить потом индекс по вычисляемому полю, но может сразу делать хорошо, плохо само получиться? Вьюхи вообще прозрачны для планировщика (кроме материализованных или имеющих триггеры), это просто подстановка текста, не более того - посмотрите текст который идет на компиляцию.


    1. Fromych
      26.08.2026 00:37

      Так функциональные индексы для того и придумали, чтобы спасать кривые схемы без даун тайма. Навесил индекс на выражение и пошел спать, зачем трагедию из этого устраивать)


    1. FrolovAlexander Автор
      26.08.2026 00:37

      Функциональный индекс на ((created_at)::date) это правильный фикс. В статье показано, почему без него планировщик не может использовать индекс (merchant_id, created_at), view выставляет наружу day как выражение, а не колонку. Функциональный индекс решает, но требует DDL и понимания, что view «молча» ломает саргабельность, именно этот момент показателен, без вникания и проверок можно попасть на ровном месте.


  1. iamkisly
    26.08.2026 00:37

    По моему у ТС какие-то тараканы в голове. Шутки на собеседовании это просто средство разрядки атмосферы. В практике ТС они видимо не используются, так же как и вью.


  1. vvm13xx
    26.08.2026 00:37

    Насколько я понял, у ТС базы примитивной структуры и примитивные запросы в них, со сложными предметными областями он не сталкивался. У многих комментаторов выше, по-видимому, аналогично. Совершенно естественно, что VIEW им не особо полезны.


  1. dvvarna
    26.08.2026 00:37

    Представления полезны как прослойка между клиентской частью и таблицами с данными.
    Клиентская часть не имеет прямого доступа к данным, не знает структуру БД, что полезно для безопасности, ну и для разработки полезно то что внутри структуру таблиц можно менять, а клиенту в представлении показывать всё неизменно по структуре и клиентскую часть не надо будет изменять, ну или делать это значительно реже.


  1. fiftin_men
    26.08.2026 00:37

    Хотя статья написано или пропущена через нейронку на 100%, комментаторы не отстают. Либо выдают шаблонные ответы, либо отвечают не по сути. В статье приведены замеры, а в ответ: ну так ведь удобней, ну у автора примитивные данные, наверно. Один про фому, другие про ерёму.


  1. shy
    26.08.2026 00:37

    Ми когда-то view кодом генерили (очень давно), это были своего рода ui настройки. Самое первое предназначение было - делать запросы короче (текст запроса).


  1. Fromych
    26.08.2026 00:37

    Поднять стенд с двумя базами и нагенерить миллионы строк чисто из-за уязвленного эго на собесе прям база. Сам так делал, когда доказывал лиду, что его новая архитектура не взлетит)


  1. stiz
    26.08.2026 00:37

    Мы вьюхи применяем если надо в ходе интеграции предоставить доступ к чётко оговорённым данным. Исполнитель на бэке может поленится и забрать из таблиц все столбцы. Вьюха же не отдаёт ничего лишнего.


  1. brom_portret
    26.08.2026 00:37

    кмк вьюхи это прежде всего следствие концепта что база владеет моделью и предоставляет интерфейс в виде не только в виде запросов но и вьюх и хранимок и функций. Раньше (90е - 00е) было много проектов в такой парадигме, но пришел ORM и микросервисы. Если вы используете ORM или у вас сложная разделенная модель и база уже не владеет моделью вьюхи вам особой пользы и не принесут.


  1. achekalin
    26.08.2026 00:37

    Статья полезнее как учебник «не рассуждай о SQL абстрактно — смотри план», чем как статья «VIEW плохи». Иронично, но эксперимент скорее реабилитирует VIEW: почти во всех местах, где происходит что‑то странное, виноват не объект VIEW, а форма relational expression, индексы или границы оптимизации.


  1. slonopotamus
    26.08.2026 00:37

    у PostgreSQL work_mem дефолтные 4 МБ

    Очень зря. Постгрес надо настраивать под доступные ресурсы, хотя бы базово.


    1. FrolovAlexander Автор
      26.08.2026 00:37

      Согласен, 4 МБ это дефолт, специально оставил "как из коробки", чтобы показать поведение по умолчанию. Обычно work_mem поднимают, тогда каскад не скидывается на диск и PostgreSQL выигрывает у прямого запроса за счёт параллелизма. В статье это в разделе "Каскад": поменяйте work_mem, и цифры поедут.


  1. gybson_63
    26.08.2026 00:37

    View просто еще один уровень абстракции поверх данных. Вы можете предоставлять view как удобный контракт получения данных, такой же как REST или RPC. Предоставили view, сказали сервису строку подключения и готово. Звучит архаично, но работать будет.


  1. Fedyaration
    26.08.2026 00:37

    Спасибо за замеры и за план запроса — обычно про вью спорят на уровне ощущений, без цифр. Интересно было бы увидеть то же самое на объёме побольше и с индексом по created_at.


  1. gotch
    26.08.2026 00:37

    В базе Microsoft SCCM (ConfigMgr, Endpoint Manager) view используются повсеместно. Схему исходных таблиц иначе как замечательной не назовешь.

    Плюс это позволяет менять физическую структуру таблиц при обновлении продукта, ничего не меняя в клиентской обвязке.

    Сами оцените:

    CREATE VIEW [dbo].[v_DistributionPoint] AS 
      SELECT pkgdp.PkgID As 'PackageID', CASE WHEN ci.ModelName IS NULL THEN pkgdp.PkgID ELSE ci.ModelName END As 'SecureObjectID', pkgdp.NALPath As 'ServerNALPath', pkgdp.SiteCode, pkgdp.RefreshTrigger as 'RefreshNow',  
             pkgdp.SiteName, pkgdp.SourceSite, pkgdp.LastRefresh As 'LastRefreshTime', pkgdp.Action As 'Status',  
             dp.IsPeerDP, dp.IsBITS as 'BitsEnabled', dp.IsMulticast, CASE WHEN dp.IsProtected = 0 THEN 1 ELSE 0 END AS IsProtected, dp.PreStagingAllowed, dp.Type as 'ResourceType', pkg.PackageType, 
             dp.RemoveWDS, 
             dp.IsPXE, 
             dp.SccmPXE, 
             dp.IsActive, 
             dp.ResponseDelay, 
             dp.UdaSetting, 
             dp.BindPolicy, 
             dp.SupportUnknownMachines, 
             dp.PXEPassword, 
             dp.IdentityGUID, 
             dp.BindExcept, 
             dp.CertificateType, 
    		 pkgdp.ISVString, 
             CASE WHEN ci.ModelName IS NOT NULL THEN 31 ELSE pt.SecuredTypeID END AS ObjectTypeID, 
             CASE WHEN ISNULL(dp.Type, 'Windows NT Server') = N'Windows Azure' THEN 1 ELSE 0 END AS IsCloud 
        FROM PkgServers AS pkgdp  
        LEFT JOIN DistributionPoints dp on dp.NALPath=pkgdp.NALPath  
        JOIN SMSPackages AS pkg on pkgdp.PkgID=pkg.PkgID 
        LEFT JOIN (vSMS_CIContentPackage AS ci INNER JOIN CI_ConfigurationItems AS cii ON cii.CI_ID = ci.CI_ID AND cii.IsLatest = 1 AND cii.IsTombstoned = 0) ON pkg.PkgID = ci.PkgID 
        LEFT JOIN SMSPackageTypes pt on pt.PackageTypeID=pkg.PackageType 
      WHERE dp.DPFlags <> 1 AND pkgdp.Action <> 3