ТОП-20 проблем DWH

Реальные findings

Подбор пакетов | Кейсы | Глоссарий
#1CRITICAL
Расхождение управленческой и регуляторной отчётности
Баланс не сходится с формами ЦБ
В банке ТОП-50 обнаружили расхождение 340M ₽ между управленческим балансом и формой 101 ЦБ. Ошибка присутствовала 8 месяцев и затронула все квартальные отчёты.
Impact
Штрафы ЦБ (до 0.1% активов), пересдача отчётности за 3 квартала, потеря доверия регулятора
Effort
1 нед. диагностика + 1 нед. исправление + 2 нед. пересчёт + ongoing мониторинг
🔍 КАК НАХОДИМ
1.Строим матрицу сверок: 50 пар «управленч. показатель ↔ строка формы ЦБ»
2.Запускаем параллельный расчёт обоих контуров на одну дату
3.Выявляем ячейки с дельтой > порога (0.01%)
4.Для каждого расхождения трассируем SQL: mart → ODS → staging → source
5.На слое staging обнаруживаем: курс ЦБ берётся на T-1 вместо T для валютных переоценок
6.Проверяем историю: ошибка с момента рефакторинга ETL 8 мес. назад
✓ КАК ИСПРАВЛЯЕМ
1.Создать единый справочник курсов ЦБ с версионированием (SCD Type 2)
2.Исправить SQL валютных переоценок: ref.cbr_rates WHERE dt = report_date (не dt = report_date - 1)
3.Пересчитать затронутые периоды
4.Внедрить автотест: ежедневная сверка |управленч. - регуляторный| < 0.01% с алертом в Slack
5.Добавить reconciliation checkpoint на стыке staging→ODS для курсов
МОДУЛИ
M6 R1 R2 Q3
#2CRITICAL
Bus factor = 1 на ETL
Весь код DWH в голове одного человека
94% коммитов от одного разработчика. 47 витрин без единого комментария. При его отпуске — 3 дня простоя: никто не знал как перезапустить упавший pipeline и какие витрины от каких зависят.
Impact
Полный паралич DWH при уходе/болезни/отпуске ключевого сотрудника. Стоимость простоя: ~500K ₽/день для среднего банка
Effort
2 нед. срочная документация + 2 мес. менторинг + ongoing code review
🔍 КАК НАХОДИМ
1.Анализ git-логов: распределение commits по авторам (git shortlog -sn)
2.Анализ code ownership: для каждого файла — кто последний менял, кто единственный автор
3.Интервью с командой: 'кто может объяснить логику витрины X?' — если ответ один человек, это bus factor=1
4.Проверка документации: wiki, confluence, README — обычно пусто
5.Тест: попросить другого разработчика разобраться в случайной витрине — замерить время (обычно >1 дня)
✓ КАК ИСПРАВЛЯЕМ
1.Экстренно: парные сессии — ключевой человек объясняет логику, второй документирует (2ч/день, 2 нед.)
2.Data dictionary: автогенерация из DDL + ручное описание бизнес-логики для каждой витрины
3.Обязательный code review: ни один PR не мерджится без ревью вторым человеком
4.dbt docs generate для автоматического lineage
5.Менторинг junior: 2 месяца, пока не сможет самостоятельно поддерживать 50% витрин
6.Cross-training: каждый разработчик знает минимум 2 чужих домена
МОДУЛИ
A4 D7 K2 E1
#3CRITICAL
PII-данные без маскировки в DWH
Персональные данные 2M+ клиентов в открытом виде
PII-сканирование выявило: ФИО в 23 таблицах, паспортные данные в 8, СНИЛС в 5, ИНН в 18, телефоны в 12. Доступ к этим таблицам имели 47 ролей, включая 15 аналитиков, которым PII не нужны для работы.
Impact
Нарушение 152-ФЗ (штраф до 18M ₽ с 2024). Утечка = уголовное дело. Репутационные потери невосполнимы.
Effort
1 нед. сканирование + 2 нед. маскировка + 1 нед. RBAC + ongoing процесс
🔍 КАК НАХОДИМ
1.Автоматический PII-сканер: regex по 10 паттернам (\d{3}-\d{3}-\d{3} \d{2} для СНИЛС, \d{4} \d{6} для паспорта и т.д.) по ВСЕМ таблицам
2.Для каждого найденного поля: проверить тип данных, sampling 1000 строк, подтвердить PII
3.Анализ RBAC: какие роли имеют SELECT на таблицы с PII (pg_roles + information_schema)
4.Анализ приложений: какие сервисы реально читают эти данные — логирование SELECT за 30 дней
5.Классификация: для каждого PII-поля — нужно ли оно в этой таблице вообще, или это транзитная копия
✓ КАК ИСПРАВЛЯЕМ
1.PII-карта: реестр всех PII-полей с классификацией (обязательное/избыточное)
2.Column-level masking: SHA-256 хеширование для аналитических целей, tokenization для обратимых
3.View-based security: аналитики видят замаскированные view, а не raw таблицы
4.Пересмотр RBAC: revoke SELECT на raw таблицы, grant на маскированные view
5.pgaudit: включить логирование всех SELECT к таблицам с PII
6.Процесс: при создании новой таблицы — обязательная PII-классификация перед деплоем
МОДУЛИ
S1 S2 S4 G1
#4HIGH
Витрины без единого DQ-теста
Ошибки находят пользователи, а не система
0 из 50 витрин покрыты автотестами. Типичный цикл: аналитик открывает дашборд → видит аномалию → пишет в Slack → DWH-команда расследует 2-4 часа → находит NULL в source → патчит вручную. Повторяется 3-5 раз в неделю.
Impact
15-20 человеко-часов/неделю на расследования. Бизнес не доверяет данным. Решения принимаются по ощущениям, а не по данным.
Effort
2 нед. пилот + 1 мес. масштабирование + ongoing поддержка
🔍 КАК НАХОДИМ
1.Инвентаризация: сколько витрин, сколько DQ-правил, сколько инцидентов за 12 мес.
2.Анализ инцидент-лога: категоризация по root cause (NULL в source, дубли, stale data, wrong join)
3.Profiling критичных таблиц: NULL%, дубли ключей, outliers, referential integrity
4.Интервью с бизнесом: 'какие данные вы перепроверяете вручную каждый раз?' — это и есть недостающие DQ-правила
5.Benchmark: сравнение с DQ Maturity Model (6 измерений, 5 уровней)
✓ КАК ИСПРАВЛЯЕМ
1.Пилот на 20 таблицах: 80 DQ-правил в dbt tests (not_null, unique, accepted_values, relationships)
2.Custom tests для бизнес-правил: SUM(debit) = SUM(credit), portfolio_amount > 0, date_from < date_to
3.Freshness monitoring: dbt source freshness — алерт если данные старше 4 часов
4.DQ-дашборд: score по каждой таблице, trend за 30 дней, топ-нарушений
5.Runbook: что делать при каждом типе DQ-нарушения (авто-retry, уведомление, блокировка)
6.Масштабирование: +20 таблиц каждый спринт до полного покрытия
МОДУЛИ
Q1 Q5 Q2
#5HIGH
Отсутствие Data Lineage
Невозможно проследить путь данных от источника до отчёта
Никто не может ответить на вопрос регулятора 'откуда берётся цифра в строке 5 формы 123'. Расследование одного расхождения: вручную читать SQL витрины → найти source → проследить ETL-цепочку. Это 3-5 рабочих дней на ОДНО расхождение.
Impact
30-45 человеко-дней/год на расследования. Невозможность ответить на вопросы аудиторов. Невозможность оценить impact от изменения source-системы.
Effort
2 нед. (ручной) / 4 нед. (автоматический) / 2-3 мес. (полный каталог)
🔍 КАК НАХОДИМ
1.Тест: попросить команду проследить путь конкретного поля от отчёта до source — замерить время
2.Инвентаризация: есть ли lineage в каком-либо виде (Excel, wiki, DataHub)
3.Анализ SQL: автоматический parsing SELECT/FROM/JOIN для построения графа зависимостей
4.Проверка dbt: если используется — dbt docs generate даёт lineage бесплатно
5.Gap-анализ: какие таблицы не покрыты lineage, какие слои отсутствуют (обычно staging↔source)
✓ КАК ИСПРАВЛЯЕМ
1.Быстро (2 нед.): ручной lineage в Excel для ТОП-20 критичных витрин — от source до report
2.Среднесрочно (4 нед.): dbt lineage (если используется dbt) или SQL-parser для автоматического grafа
3.Долгосрочно (2-3 мес.): DataHub / Amundsen / Apache Atlas для полного каталога с lineage
4.Процесс: при создании новой витрины — lineage обязателен (часть DoD)
5.Визуализация: интерактивная HTML-карта lineage, встроенная во внутренний портал
МОДУЛИ
R3 A5 D7
#6HIGH
ETL падает молча — данные устаревают без алертов
Об ошибках узнают от бизнеса утром
Airflow DAG упал в 03:00. Данные не обновились. Никто не заметил до 10:00, когда CFO открыл дашборд. Причина: нет callback на failure, нет freshness monitoring, retry без idempotency создаёт дубли.
Impact
7+ часов задержки данных. Решения на устаревших данных. При retry без idempotency — дубликаты в mart.
Effort
2-3 дня алерты + 1 нед. idempotency + 1 нед. runbook
🔍 КАК НАХОДИМ
1.Аудит Airflow: проверить on_failure_callback на всех DAGs — обычно None
2.Проверить retry-policy: есть ли retries, есть ли idempotency (TRUNCATE + INSERT vs INSERT)
3.Анализ логов за 30 дней: сколько DAGs падали, сколько из них были обнаружены алертом vs вручную
4.Freshness check: для каждой витрины — когда последний раз обновлялась, есть ли SLA
5.Тест восстановления: специально уронить некритичный DAG ночью — через сколько заметят
✓ КАК ИСПРАВЛЯЕМ
1.Алерты: on_failure_callback → Slack + email для всех DAGs (1 день)
2.Freshness: dbt source freshness + Grafana дашборд с SLA по каждой витрине
3.Idempotency: TRUNCATE + INSERT или MERGE вместо INSERT для всех загрузок
4.Dead man's switch: если DAG НЕ запустился по расписанию — алерт
5.Runbook: для каждого DAG — что делать при падении, кого эскалировать, какой impact
МОДУЛИ
G3 G5 Q5
#7HIGH
Хардкод дат и магических чисел в SQL
WHERE dt = '2023-01-01' вместо параметра в 30% кода
В 47 из 150 SQL-файлов — хардкод-даты, магические числа (WHERE type_id = 7 — что такое 7?), хардкод-имена серверов. При смене отчётного периода — ручная правка 50+ файлов. Одна пропущенная замена = расхождение в отчёте, обнаруживается через дни.
Impact
2-4 часа ручной правки каждый месяц. 1-2 инцидента в квартал из-за пропущенной замены. Невозможность перезапустить за прошлый период без правки кода.
Effort
3-5 дней рефакторинг ТОП-20 + ongoing CI-правило
🔍 КАК НАХОДИМ
1.Статический анализ: grep по паттернам хардкода (даты, числовые литералы в WHERE, имена серверов)
2.sqlfluff lint с custom rules: no-hardcoded-dates, no-magic-numbers
3.Code review: выборочная проверка 20 витрин — классификация хардкода по типам
4.Impact assessment: для каждого хардкода — что произойдёт при смене периода
5.Dependency map: какие витрины зависят от каких параметров — матрица
✓ КАК ИСПРАВЛЯЕМ
1.Параметризация: dbt vars / Airflow variables / environment config для дат и периодов
2.Справочники: магические числа → ref-таблицы с описанием (type_id=7 → ref.types WHERE name='Кредит')
3.sqlfluff CI: запрет хардкода в PR — не пройдёт review
4.Рефакторинг: поэтапная замена хардкода в порядке критичности (регуляторные формы → управленч. → аналитика)
5.Конфиг-файл: единый config.yml с параметрами среды (серверы, пути, пороги)
МОДУЛИ
L1 L4 G2 L3
#8HIGH
ECL-модель живёт в Excel, а не в DWH
Резервы IFRS 9 на 50K инструментов считаются в xlsx с VBA
ECL-модель для всего кредитного портфеля — Excel-файл с 20 вкладками и VBA-макросами на сетевом диске. Нет version control, нет audit trail, нет автотестов. Один человек знает формулы. При аудите Big4 — вопросы к воспроизводимости.
Impact
Риск ошибки в резервах (масштаб: миллиарды ₽). Невоспроизводимость расчёта. Вопросы аудиторов Big4 при каждой проверке.
Effort
4-8 нед. миграция + 3 мес. dual-run + ongoing поддержка
🔍 КАК НАХОДИМ
1.Интервью с МСФО-командой: 'где считается ECL, кто владелец, есть ли version control'
2.Аудит Excel: проверка формул, VBA-макросов, consistency между вкладками
3.Параллельный расчёт: взять те же данные и посчитать ECL в SQL/Python — сравнить с Excel
4.Backtesting: PD, которые были год назад — совпали ли с фактическими дефолтами?
5.Stress-testing: изменить один параметр (PD +10%) — как меняется итоговый ECL? Адекватна ли чувствительность?
✓ КАК ИСПРАВЛЯЕМ
1.Перенос расчёта ECL в SQL/Python внутри DWH (4-6 нед.)
2.Git для version control: каждое изменение — commit с описанием
3.Автотесты: PD/LGD backtesting, stage migration consistency, ECL sensiti­vity
4.Audit trail: логирование каждого запуска с параметрами и результатом
5.Документация: методика расчёта + маппинг на IFRS 9 стандарт
6.Dual-run: 3 мес. параллельного расчёта Excel vs DWH до полного перехода
МОДУЛИ
F1 F2 D2
#9HIGH
Нет CI/CD — деплой через copy-paste в pgAdmin
SQL деплоится вручную, без тестов и ревью
Процесс: разработчик копирует SQL из IDE → вставляет в pgAdmin → нажимает Execute → идёт пить кофе. Нет git (код на локальных машинах), нет code review, нет тестов, нет rollback. За квартал — 3 production-инцидента из-за опечаток.
Impact
3 production-инцидента/квартал × 4 часа восстановления = 48 часов простоя/год. Невозможность отката. Потеря кода при смене компьютера.
Effort
1-2 нед. настройка CI/CD + 1 нед. миграция кода в git
🔍 КАК НАХОДИМ
1.Интервью: 'как вы деплоите код в production?' — если ответ 'pgAdmin/DBeaver', это оно
2.Проверка: есть ли git-репозиторий? Сколько коммитов за последний месяц? Кто коммитит?
3.Анализ инцидентов: сколько из них связаны с деплоем (опечатка, не тот сервер, забыли WHERE)
4.Проверка rollback: 'как откатить последнее изменение?' — обычно 'никак' или 'из бэкапа'
5.Тест: специально внести typo в тестовый SQL — пройдёт ли через deploy процесс?
✓ КАК ИСПРАВЛЯЕМ
1.Git: перенести весь SQL в репозиторий (1-2 дня)
2.PR-workflow: branch → code → PR → review → merge → auto-deploy
3.sqlfluff: линтинг SQL в CI — блокирует PR при ошибках стиля
4.dbt test: автотесты перед деплоем — блокирует деплой при regression
5.Rollback: git revert + auto-deploy = откат за 5 минут
6.Environments: dev → staging → prod с автоматическим продвижением
МОДУЛИ
D8 G2 L3
#10HIGH
Отсутствие reconciliation между слоями DWH
Данные теряются или дублируются между staging и mart
Никто не проверяет: все ли записи из source попали в staging? Все ли из staging — в ODS? Правильно ли агрегированы в mart? Обнаруживается случайно: бизнес заметил, что портфель уменьшился на 2% — оказалось, загрузка потеряла 1 день из staging.
Impact
Неполные данные в отчётах. Потеря 1 дня данных = ошибка в форме ЦБ. Обнаружение через недели.
Effort
1 нед. базовые checkpoints + 2 нед. полная матрица сверок
🔍 КАК НАХОДИМ
1.Для каждого стыка (source→staging, staging→ODS, ODS→mart): SELECT COUNT(*), SUM(amount) на обоих сторонах
2.Анализ паттернов: есть ли дни с нулевой загрузкой? Резкие провалы/скачки в COUNT?
3.Referential integrity: все ли FK в mart ссылаются на существующие записи в ODS?
4.Хронология: timestamp последней записи в staging vs source — есть ли gap?
5.Дубликаты: уникальность бизнес-ключей на каждом слое
✓ КАК ИСПРАВЛЯЕМ
1.Reconciliation checkpoints: автосверка COUNT/SUM после каждой загрузки
2.dbt tests: relationships (FK consistency), unique, not_null на каждом слое
3.Алерт: |delta| > 0.1% → Slack + блокировка следующего шага ETL
4.Дашборд: reconciliation матрица по всем стыкам, daily trend
5.Dead letter queue: записи, не прошедшие reconciliation, — в отдельную таблицу для расследования
МОДУЛИ
Q3 L2 G3
#11MEDIUM
SELECT * в production-витринах
24% витрин читают 100% колонок вместо нужных 20%
12 из 50 витрин используют SELECT * вместо явного списка полей. Для wide tables (100+ колонок) — читается 5x больше данных, чем нужно. Плюс при ALTER TABLE ADD COLUMN — витрина может сломаться или вернуть неожиданные данные.
Impact
Перерасход I/O на 200-300%. Замедление дашбордов. Неожиданные поломки при DDL-изменениях.
Effort
1-2 дня рефакторинг 12 витрин + CI-правило
🔍 КАК НАХОДИМ
1.Статический анализ: grep -r 'SELECT \*' по всем SQL-файлам + dbt моделям
2.Для каждого SELECT *: определить, сколько колонок реально используется downstream
3.pg_stat_user_tables: сравнить seq_scan cost для витрин с SELECT * vs с явным списком
4.EXPLAIN ANALYZE: оценить разницу в I/O и времени выполнения
✓ КАК ИСПРАВЛЯЕМ
1.Заменить SELECT * на явный список полей (по одной витрине в день)
2.sqlfluff правило: no-select-star в CI — блокирует новый код
3.Code review checklist: SELECT * запрещён в production
4.Мониторинг: алерт при появлении нового SELECT * в репозитории
МОДУЛИ
L1 G4 L3
#12MEDIUM
Справочники с массовыми дубликатами
Один клиент = 3.2 записи в среднем из-за отсутствия дедупликации
Справочник клиентов: 1.2M записей, но уникальных клиентов ~375K. Причина: данные приходят из 4 АБС без дедупликации. Один клиент — разные ФИО (опечатки), разные ИНН (из разных систем). Последствия: портфель завышен на 15%, ECL некорректен.
Impact
Искажение портфельной отчётности на 15%. Некорректный ECL (задвоение экспозиции). Ошибки в сегментации.
Effort
2-3 нед. дедупликация + ongoing MDM процесс
🔍 КАК НАХОДИМ
1.Дубликаты по точному совпадению: GROUP BY inn HAVING COUNT(*) > 1
2.Fuzzy matching: Levenshtein distance < 3 для ФИО + совпадение даты рождения
3.Phonetic matching: Soundex/Metaphone для вариаций написания
4.Cross-source analysis: один и тот же клиент в разных АБС — как представлен
5.Impact: пересчитать портфельные показатели с дедупликацией vs без
✓ КАК ИСПРАВЛЯЕМ
1.Master Data Management: определить golden record для каждого клиента
2.Дедупликация: fuzzy matching + ручная верификация для неоднозначных пар
3.ID-маппинг: таблица client_id_mapping (source_id → master_id)
4.ETL: при загрузке — обязательная проверка через маппинг
5.Мониторинг: DQ-правило на прирост справочника (>5% в месяц = алерт)
МОДУЛИ
A3 Q3 Q1
#13MEDIUM
3 стиля именования в одном слое DWH
camelCase + snake_case + UPPERCASE — невозможно найти таблицу
В mart из 200 таблиц: 45% snake_case, 35% camelCase, 20% UPPERCASE. Разработчики из разных эпох — каждый писал как привык. При JOIN — ошибки case-sensitivity. Онбординг нового человека: 2 недели вместо 3 дней.
Impact
Увеличение онбординга в 4x. Ошибки в JOIN из-за case. Невозможность автоматизации.
Effort
2-4 нед. поэтапная миграция с alias
🔍 КАК НАХОДИМ
1.Inventory: SELECT table_name, CASE classification FROM information_schema.tables
2.Анализ по эпохам: naming convention коррелирует с автором и годом создания
3.Оценка impact: сколько downstream зависимостей у каждой таблицы (чем больше — тем дороже переименовать)
✓ КАК ИСПРАВЛЯЕМ
1.Принять стандарт: snake_case (рекомендация PostgreSQL)
2.Поэтапная миграция: начать с leaf-таблиц (без downstream), двигаться к core
3.Alias: CREATE VIEW new_name AS SELECT * FROM old_name — для обратной совместимости
4.sqlfluff: правило naming convention в CI
5.Data dictionary: каждая новая таблица — по стандарту, без исключений
МОДУЛИ
A1 A4
#14MEDIUM
Медленные дашборды — 30-60 секунд на загрузку
BI-аналитики теряют 30-60 минут в день на ожидание
Пользователи BI жалуются: каждый дашборд грузится минуту. Причины: full table scan на 500M строк (нет индексов), nested subqueries вместо materialized views, 100+ полей в SELECT, CROSS JOIN в одном чарте.
Impact
20 аналитиков × 30 мин/день = 10 человеко-часов/день = 200 ч/мес потерь
Effort
3-5 дней оптимизация ТОП-20 запросов (эффект: среднее время 45с → 3с)
🔍 КАК НАХОДИМ
1.pg_stat_statements: ТОП-20 slow queries по total_time и calls
2.EXPLAIN ANALYZE каждого: Seq Scan? Nested Loop? Sort?
3.Проверка индексов: покрывают ли индексы WHERE и JOIN условия запросов
4.Table bloat: pg_stat_user_tables.n_dead_tup — нужен ли VACUUM?
5.Partitioning: большие таблицы партиционированы по дате?
✓ КАК ИСПРАВЛЯЕМ
1.Индексы: CREATE INDEX на WHERE/JOIN поля ТОП-20 запросов (1 день, эффект: 10-50x)
2.Materialized views: для тяжёлых агрегаций (REFRESH CONCURRENTLY по расписанию)
3.Партиционирование: ALTER TABLE PARTITION BY RANGE (dt) для таблиц >100M строк
4.Query rewrite: убрать CROSS JOIN, заменить nested subquery на CTE/JOIN
5.VACUUM FULL: для таблиц с bloat >30%
МОДУЛИ
B4 G4 A2
#15MEDIUM
Orphaned accounts с admin-правами
15 учёток уволенных сотрудников с полным доступом к DWH
Аудит pg_roles: 15 активных учётных записей людей, уволенных 6-24 мес. назад. 3 из них — superuser. 1 учётка используется автоматическим скриптом, но привязана к уволенному. Offboarding checklist не включает отзыв доступов к DWH.
Impact
Несанкционированный доступ. Compliance violation (152-ФЗ, ЦБ). Потенциальная утечка.
Effort
1 день cleanup + процесс quarterly review
🔍 КАК НАХОДИМ
1.Сравнить pg_roles с HR-системой: кто есть в DWH, но нет в списке сотрудников
2.pg_stat_activity: какие из orphaned accounts были активны за последние 90 дней
3.pgaudit: какие запросы выполнялись с этих учёток
4.Service accounts: какие учётки привязаны к сервисам, а не к людям — есть ли владелец
5.Privilege escalation: кто может GRANT другим, кто superuser, кто CREATEROLE
✓ КАК ИСПРАВЛЯЕМ
1.Немедленно: DROP/DISABLE orphaned accounts (1 час)
2.Service accounts: переименовать svc_xxx, документировать владельца, убрать superuser
3.Offboarding: добавить 'revoke DWH access' в HR offboarding checklist
4.Quarterly review: автоматическая сверка pg_roles vs HR каждый квартал
5.Principle of least privilege: REVOKE ALL, GRANT SELECT ON specific tables
МОДУЛИ
G1 S3
#16MEDIUM
Отсутствие партиционирования больших таблиц
500M строк без партиций — каждый запрос = full table scan
Факт-таблица транзакций: 500M строк, 200GB, без партиций. Каждый запрос с WHERE dt BETWEEN — full table scan на 200GB. Autovacuum не справляется → table bloat 40%. При запросе за 1 день сканируется весь год.
Impact
Запросы в 10-50x медленнее чем могли бы. Bloat = перерасход 80GB диска. VACUUM FULL = downtime.
Effort
1-2 дня планирование + 1 день миграция (при maintenance window)
🔍 КАК НАХОДИМ
1.Инвентаризация: SELECT schemaname, tablename, pg_total_relation_size(schemaname||'.'||tablename) ORDER BY 3 DESC
2.Проверка партиций: partitioned tables vs обычные
3.Анализ запросов: какие WHERE-условия используются (обычно дата)
4.Bloat: расчёт dead tuples vs live tuples
5.Performance: EXPLAIN ANALYZE типичного запроса — Seq Scan vs Index Scan
✓ КАК ИСПРАВЛЯЕМ
1.Партиционирование: CREATE TABLE ... PARTITION BY RANGE (dt) — monthly partitions
2.Миграция: pg_partman или ручной ALTER TABLE ATTACH PARTITION
3.VACUUM FULL: после миграции для устранения bloat
4.Автоматизация: cron для создания будущих партиций (на 3 мес. вперёд)
5.Мониторинг: алерт если партиция не создана / размер партиции аномальный
МОДУЛИ
A2 D9
#17MEDIUM
Ручные корректировки перед отправкой форм ЦБ
Бухгалтерия правит 10-15 ячеек в Excel каждый месяц без audit trail
Перед отправкой форм ЦБ бухгалтерия вручную правит ячейки: 'тут не сходится на 3 копейки', 'тут рубль потерялся'. Причина: ошибки округления, несовпадение методик. Нет audit trail — неизвестно какие ячейки правились, почему, кем.
Impact
Нет аудируемости. Риск ошибки при ручной правке. Гарантированное замечание при проверке ЦБ.
Effort
1-2 нед. root cause analysis + 1 нед. fix + ongoing цель 0 правок
🔍 КАК НАХОДИМ
1.Интервью: 'вы правите формы вручную перед отправкой?' — обычно 'да, каждый раз'
2.Анализ: какие именно ячейки правятся, какие суммы, в какую сторону
3.Root cause: почему не сходится — округление? разные методики? ошибка в SQL? timing?
4.Для каждой правки: воспроизвести расхождение в SQL, найти строку кода с ошибкой
5.Оценка масштаба: сколько форм затронуто, сколько правок за 12 мес.
✓ КАК ИСПРАВЛЯЕМ
1.Root cause fix: исправить SQL для каждого типа расхождения
2.Округление: единая функция ROUND с банковским округлением (0.5 → ближайшее чётное)
3.Control totals: автотест |SUM(details) - control_total| < 1 ₽ с блокировкой
4.Audit trail: если ручная правка всё же нужна — форма с описанием, автором, датой
5.Процесс: цель = 0 ручных правок, каждая существующая — задача в backlog на автоматизацию
МОДУЛИ
Q4 M6 R1
#18LOW
Backup не тестировался более года
RPO и RTO неизвестны — при катастрофе неизвестно что потеряем
pg_dump по cron каждую ночь. Бэкапы на NFS. Хранение 30 дней. Но: никто ни разу не пробовал restore. RPO и RTO не определены. При реальном сбое неизвестно сколько данных потеряется и за какое время восстановимся.
Impact
Неизвестный RPO/RTO. Риск полной потери DWH. Невыполнение требований ЦБ к непрерывности.
Effort
1 день DR-тест + документация
🔍 КАК НАХОДИМ
1.Проверка: когда последний успешный backup? Есть ли мониторинг backup success/failure?
2.Где хранятся: тот же сервер? NFS? S3? Другой ДЦ? (если тот же сервер — не backup)
3.Retention: сколько дней хранятся? Хватит ли для восстановления за нужный период?
4.DR-план: есть ли документ? Когда последний раз обновлялся?
5.Тест: пробовали ли реально восстановить хотя бы одну таблицу из backup?
✓ КАК ИСПРАВЛЯЕМ
1.DR-тест: restore на standby-сервер, замерить RPO и RTO (1 день)
2.Документировать: RPO = X часов, RTO = Y часов, процедура восстановления step-by-step
3.Мониторинг: алерт если backup не завершился успешно
4.Offsite: копия backup в другой ДЦ / S3 / tape
5.Повторять: DR-тест ежеквартально, результат — в отчёт для руководства
МОДУЛИ
G6
#19LOW
Миграция BI-платформы затянулась на 14 месяцев
80% дашбордов всё ещё на старой платформе
Миграция Oracle BI → Superset начата 14 мес. назад. Мигрировано 30 из 150 дашбордов. Причины: нет маппинга Oracle SQL → PostgreSQL, каждый чарт переносится вручную, нет автотестов 'старый = новый', бизнес не хочет менять привычки.
Impact
Двойные лицензионные затраты (~5M ₽/год). Двойная поддержка (2 инструмента). Пользователи путаются.
Effort
3-6 мес. при правильном подходе (vs 14 мес. без плана)
🔍 КАК НАХОДИМ
1.Inventory: сколько дашбордов всего, сколько мигрировано, сколько активно используется
2.Usage analytics: какие дашборды реально открываются (90/150 = 40% может быть мертвыми)
3.SQL compatibility: какие Oracle SQL конструкции не поддерживаются в PostgreSQL
4.Complexity scoring: ранжировать дашборды по сложности миграции
5.Business priority: какие дашборды критичны для бизнеса (мигрировать первыми)
✓ КАК ИСПРАВЛЯЕМ
1.Приоритизация: мигрировать ТОП-30 по usage, остальные — закрыть (если не используются)
2.SQL migration toolkit: автоматическая конвертация Oracle SQL → PostgreSQL
3.Side-by-side testing: автосравнение данных старого и нового дашборда
4.Cutover plan: дата X — старая платформа отключается, deadline мотивирует
5.Training: 1-дневный тренинг для бизнес-пользователей перед cutover
МОДУЛИ
B2
#20LOW
Бизнес-аналитики используют 10% возможностей BI
Каждый ad-hoc запрос = заявка в DWH-команду (SLA 3 дня)
30 аналитиков имеют доступ к BI. Используют только готовые дашборды: открыть → посмотреть → закрыть. Не умеют: создавать чарты, менять фильтры, drill-down, экспорт в Excel, создавать алерты. Каждый нестандартный запрос → тикет в Jira → SLA 3 дня.
Impact
DWH-команда перегружена: 40 ad-hoc тикетов/мес. Аналитики не самостоятельны — ждут по 3 дня.
Effort
1-2 дня тренинг + 1 нед. материалы + ongoing office hours
🔍 КАК НАХОДИМ
1.Jira/ServiceDesk: сколько тикетов с типом 'ad-hoc запрос' за 12 мес.
2.BI usage logs: кто логинится, как часто, какие функции использует
3.Опрос аналитиков: 'что вы хотели бы делать в BI, но не умеете?'
4.Тест: попросить аналитика создать простой чарт — замерить время и уровень фрустрации
5.Benchmark: сколько % запросов бизнес может обслуживать self-service
✓ КАК ИСПРАВЛЯЕМ
1.Тренинг (6 часов): self-service BI — фильтры, drill-down, создание чартов, экспорт
2.Sandbox: датасет для практики без страха сломать production
3.Video tutorials: 5-мин видео для каждого типового сценария (10 видео)
4.Office hours: 1 час/нед — DWH-инженер отвечает на вопросы аналитиков live
5.Метрика: % запросов self-service (цель: с 10% до 60% за 3 мес.)
МОДУЛИ
B5 K4
Подобрать пакетОбсудить

Бесплатная диагностика

3–5 витрин · 5–10 findings · за 3–5 дней · без обязательств

📩
Оставьте заявку
Имя, компания, задача — 30 секунд
🤝
Встреча с архитектором
30 минут онлайн — обсуждаем боли и стек
🔎
Quick scan 3–5 витрин
Подключаемся read-only, находим реальные проблемы
📋
Отчёт с SQL-доказательствами
5–10 findings + рекомендации. Без обязательств.
Quick scan бесплатно →
Ответим в течение 4 часов
Quick scan: 5–10 findings за 3–5 дней
Бесплатно · без обязательств
contact@dgbyte.ru