Месячные отчёты расчётного центра, который начисляет плату за жилищно-коммунальные услуги, раньше считались всю ночь, а теперь успевают к утру. Евгений Росляков переписал их на PL/SQL внутри базы Oracle и заодно упростил самые частые экраны операторов в Oracle Forms. Он работает с базами и веб-системами с 2016 года. Статус у него самозанятый, перед стартом он подписывает договор, а юрлицам даёт закрывающие документы. Москва — его город, а заказчиков из других мест он ведёт удалённо.
Центр начисляет плату по нескольким районам города в России. Месячные сводки нужны управляющим компаниям и ресурсоснабжающим организациям, и ждут их к определённому сроку.
База начислений стоит на собственной установке Oracle 11g. Лицензии куплены много лет назад, поддержки у производителя нет, патчей и обновлений не будет. Значит, работать надо осторожно и не рассчитывать, что вендор выручит, если что-то сломается.
Операторы сидят в экранах на Oracle Forms. За годы формы обросли полями, которыми почти никто не пользуется. Оператор искал нужный лицевой счёт среди десятков полей, путался и вводил лишнее.
Хуже всего было с отчётами. Месячные сводки считались всю ночь и иногда не успевали к утру. Управляющие компании ждали, сотрудники центра нервничали и перезапускали расчёт.
Условия задачи были ясные: ускорить отчёты, не изменив ни одной цифры, и разгрузить самые частые экраны. Менять базу на другую никто не собирался.
Сначала разобрался, куда уходит время. Посмотрел планы выполнения самых тяжёлых запросов, нашёл полные просмотры больших таблиц и места без индексов. Главная беда оказалась в построчных циклах: отчёт брал один лицевой счёт, считал, брал следующий, и так по тысячам.
Отчёты я переписал в пакетах на PL/SQL, процедурном языке внутри самой базы. В техзадании клиента он значился как Oracle PL/SQL, но суть та же. Вместо обработки по одной строке теперь массовая: BULK COLLECT читает пачку строк за раз, FORALL записывает пачку за раз. Промежуточные агрегаты по лицевым счетам считаются один раз, и ими пользуются несколько отчётов. Недостающие индексы добавил.
В такой работе нельзя потерять точность. Поэтому каждый новый отчёт за прошлые месяцы сверял со старым по каждой строке, а не по итогам. Расхождения разбирали вместе с сотрудниками центра. Часть оказалась ошибками округления в старом коде, и мы договорились, какое поведение считать верным.
Новый интерфейс в Oracle Forms строить не стал. Упростил то, чем пользуются чаще всего: поиск лицевого счёта, перерасчёт, печать квитанции. Убрал лишние поля, добавил проверки ввода, чтобы заведомо неверное значение нельзя было сохранить.
Ночная выгрузка платежей от банков и сверка теперь ведут журнал ошибок. Строка, которая не разобралась, попадает в журнал с причиной, а остальные идут дальше. Утром оператор открывает список и разбирает его, а не ищет, где всё сломалось.
Любое изменение сначала проверял на копии базы, а перед выпуском делал резервную копию: Oracle 11g давно устарела, и права на ошибку не было.
Месячные сводки готовы к утру с запасом. Расчёт не нужно перезапускать, управляющие компании получают данные вовремя.
Цифры совпали со старыми отчётами во всех проверенных месяцах. Это было главным условием, без него скорость ничего не стоила бы.
Операторам стало проще. Найти лицевой счёт, сделать перерасчёт и распечатать квитанцию можно за несколько действий, лишние поля не лезут в глаза. Новые сотрудники осваивают экраны быстрее: меньше объяснять на словах, что сюда не нужно ничего вводить.
Журнал ошибок по платежам избавил от ручных поисков. Видно, какая строка не прошла и по какой причине.
Теперь о слабом месте. Oracle 11g остаётся версией без поддержки производителя, и ускорение этого не отменяет. Я подготовил план дальнейшего перехода: куда можно переехать, что придётся переписывать в Oracle Forms и сколько времени уйдёт на проверку. Решение и бюджет за заказчиком. Пока всё работает стабильно, но надолго откладывать вопрос не стоит.
Если расчёты в базе идут всю ночь, а экраны операторов давно перегружены, опишите задачу мне на freelance.ru: версию Oracle, названия отчётов и сколько они считаются. Прикину, где можно выиграть время.